1 条题解

  • 0
    @ 2023-6-21 20:08:54

    C++ :

    #include <cstdio>
    #include <iostream>
    #include <algorithm>
    #include <string>
    #include <cstring>
    #include <map>
    #include <ctime>
    #include <vector>
    #include <stack>
    #define N 2000010
    
    using namespace std;
    
    int n,cnt,g,flg;
    int B[N],L[N],R[N],dfn[N],low[N],vis[N],wh[N],len[N],G[N];
    char *A[N];
    char M[N];
    stack<int> S;
    struct edge{
      int t,nx;
    }E[N];
    
    inline void Insert(int x,int y){
      E[++cnt].t=y; E[cnt].nx=G[x]; G[x]=cnt;
    }
    map<string,int> Mp;
    
    struct trie{
      int node[N][3],cnt,enin[N];
      trie(){ cnt=1; }
      void insert(char *a,int x,int len){
        int k=1,i=0;
        while(i<len){
          if(node[k][a[i]-'0']) k=node[k][a[i]-'0'];
          else k=node[k][a[i]-'0']=++cnt;
          i++;
        }
        enin[k]=1;
      }
      bool check(char *a,int len){
        int k=1,i=0;
        while(i<len){
          if(node[k][a[i]-'0']) k=node[k][a[i]-'0']; else return false;
          if(enin[k]) return true;
          i++;
        }
        return true;
      }
    }C;
    
    struct itrie{
      int node[N][3],cnt,enin[N],G[N],g;
      itrie(){ cnt=1;}
      void insert(char *a,int x,int len){
        int k=1,i=0;
        while(i<len){
          if(node[k][a[i]-'0']) Insert(node[k][a[i]-'0']+g,cnt+1+g);
          k=node[k][a[i]-'0']=++cnt;
          i++;
        }
        Insert(k+g,x);
        enin[k]=1;
      }
      void explore(char *a,int x,int len){
        int k=1,i=0,w=0;
        while(i<len){
          k=node[k][a[i]-'0'];
          if(enin[k]) w=k;
          i++;
        }
        if(w) Insert(x,w+g);
      }
    }D,F;
    
    void tarjan(int x){
      low[x]=dfn[x]=++g; vis[x]=1;
      S.push(x);
      for(int i=G[x];i;i=E[i].nx){
        if(!vis[E[i].t]){
          tarjan(E[i].t);
          low[x]=min(low[E[i].t],low[x]);
        }
        else if(vis[E[i].t]==1) low[x]=min(low[x],dfn[E[i].t]);
      }
      if(low[x]==dfn[x]){
        ++flg;
        while(1){
          int w=S.top(); S.pop();
          vis[w]=2;
          wh[w]=flg;
          if(w==x||S.empty()) break;
        }
      }
    }
    
    int main(){
      scanf("%d",&n);
      for(int i=1,j;i<=n;i++){
        scanf("%s",M); len[i]=strlen(M);
        int tot=++Mp[M];
        if(tot>3) return puts("NO"),0;
        A[i]=new char[strlen(M)+5];
        for(j=0;j<len[i];j++) A[i][j]=M[j];
        for(j=0;j<len[i];j++) if(A[i][j]=='?') break;
        if(j==len[i]) B[i]=-1;
        else B[i]=j;
      }
      for(int i=1;i<=n;i++)
        if(B[i]==-1) if(C.check(A[i],len[i])) return puts("NO"),0;
          else C.insert(A[i],i,len[i]);
      for(int i=1;i<=n;i++)
        if(B[i]!=-1){
          int k=0;
          A[i][B[i]]='0';
          if(C.check(A[i],len[i])) k+=1;
          A[i][B[i]]='1';
          if(C.check(A[i],len[i])) k+=2;
          if(k==3) return puts("NO"),0;
          if(!k) continue;
          if(k==1)
    	A[i][B[i]]='1',C.insert(A[i],i,len[i]);
          else
    	A[i][B[i]]='0',C.insert(A[i],i,len[i]);
          B[i]=-1;
        }
      D.g=500000; F.g=1000000;
      for(int i=1;i<=n;i++)
        if(B[i]!=-1){
          A[i][B[i]]='0';
          D.explore(A[i],i<<1|1,len[i]);
          A[i][B[i]]='1';
          D.explore(A[i],i<<1,len[i]);
          A[i][B[i]]='0';
          D.insert(A[i],i<<1,len[i]);
          A[i][B[i]]='1';
          D.insert(A[i],i<<1|1,len[i]);
        }
      for(int i=n;i;i--)
        if(B[i]!=-1){
          A[i][B[i]]='0';
          F.explore(A[i],i<<1|1,len[i]);
          A[i][B[i]]='1';
          F.explore(A[i],i<<1,len[i]);
          A[i][B[i]]='0';
          F.insert(A[i],i<<1,len[i]);
          A[i][B[i]]='1';
          F.insert(A[i],i<<1|1,len[i]);
        }
      for(int i=2;i<=(n<<1|1);i++)
        if(!vis[i]) tarjan(i);
      for(int i=1;i<=n;i++)
        if(wh[i<<1]==wh[i<<1|1]) return puts("NO"),0;
      puts("YES");
      return 0;
    }
    
    • 1

    信息

    ID
    1040
    时间
    2000ms
    内存
    512MiB
    难度
    10
    标签
    递交数
    2
    已通过
    0
    上传者