2 条题解

  • 0
    @ 2026-9-25 0:01:19

    题意:给出nn个0101串,求是否存在一个无限长的0101串,使得这nn个0101串都不是这个无限长的0101串的子串。

    我们给nn个0101串建出TrieTrie图,给每个0101串的结尾节点打上标记,代表这个点表示的字符串不能出现在构造出的串中。同时如果一个点得failfail指针带有标记,那么他自己一定也不能出现,我们给他也打上标记。问题就等价于在TrieTrie图中是否存在一个环,环上的每个节点都没有标记。直接dfsdfs即可。

    代码

    #pragma GCC optimize(2)
    #include<bits/stdc++.h>
    #include<tr1/unordered_map>
    #define re register
    #define N 30001
    #define MAX 2001
    #define inf 1e18
    #define eps 1e-10 
    using namespace std;
    typedef unsigned long long ll;
    typedef double db;
    inline void read(re ll &ret)
    {
        ret=0;re ll pd=0;re char c=getchar();
        while(!isdigit(c)){pd|=c=='-';c=getchar();}
        while(isdigit(c)){ret=(ret<<1)+(ret<<3)+(c&15);c=getchar();}
        ret=pd?-ret:ret;
        return;
    }
    ll n,trie[N][2],tot,f[N],nxt[N];
    char s[N];
    inline void insert()
    {
    	re ll p=0,len=strlen(s+1);
    	for(re int i=1;i<=len;i++)
    	{
    		re ll c=(s[i]&15);
    		if(!trie[p][c])
    			trie[p][c]=++tot;
    		p=trie[p][c];
    	}
    	f[p]=true;
    	return;
    }
    inline void bfs()
    {
    	queue<ll>q;
    	if(trie[0][0])
    		q.push(trie[0][0]);
    	if(trie[0][1])
    		q.push(trie[0][1]);
    	while(!q.empty())
    	{
    		re ll p=q.front();
    		q.pop();
    		for(re int i=0;i<2;i++)
    		{
    			if(!trie[p][i])
    				trie[p][i]=trie[nxt[p]][i];
    			else
    			{
    				nxt[trie[p][i]]=trie[nxt[p]][i];
    				f[trie[p][i]]|=f[nxt[trie[p][i]]];
    				q.push(trie[p][i]);
    			}
    		}
    	}
    	return;
    }
    tr1::unordered_map<ll,bool>vis,vst;
    inline void dfs(re ll deep)
    {
    	if(f[deep])return;
    	if(vis[deep])
    	{
    		puts("TAK");
    		exit(0);
    	}
    	if(vst[deep])
    		return;
    	vis[deep]=true;
    	vst[deep]=true;
    	dfs(trie[deep][0]);
    	dfs(trie[deep][1]);
    	vis[deep]=false;
    }
    signed main()
    {
    	read(n);
    	for(re int i=1;i<=n;i++)
    	{
    		scanf("%s",s+1);
    		insert();
    	}
    	bfs();
    	dfs(0);
    	puts("NIE");
    	exit(0);
    }
    
    • 0
      @ 2026-4-26 15:26:35
      #include<bits/stdc++.h>
      using namespace std;
      typedef long long ll;
      int n,ch[30010][2],ed[30010],fail[30010],id;
      void ins(string s){
      	int p=0;
      	for(int i=0;i<s.size();i++){
      		int j=s[i]-'0';
      		if(!ch[p][j])ch[p][j]=++id;
      		p=ch[p][j];
      	}
      	ed[p]=1;
      }
      void build(){
      	queue<int> q;
      	for(int i=0;i<2;i++)if(ch[0][i])q.push(ch[0][i]);
      	while(!q.empty()){
      		int x=q.front();
      		q.pop();
      		ed[x]|=ed[fail[x]];
      		for(int i=0;i<2;i++){
      			int &y=ch[x][i];
      			if(!y)y=ch[fail[x]][i];
      			else fail[y]=ch[fail[x]][i],q.push(y);
      		}
      	}
      }
      int deg[30010],vis[30010],fl=0;
      void dfs(int x){
      	vis[x]=1;
      	for(int i=0;i<2;i++){
      		int y=ch[x][i];
      		if(!ed[y]&&!vis[y]){
      			dfs(y);
      		}
      		else if(vis[y]==1){
      			fl=1;
      			return ;
      		}
      	}
      	vis[x]=2;
      }
      int solve(){
      	int cnt=0;
      	for(int i=0;i<=id;i++){
      		if(ed[i]){
      			cnt++;
      			vis[i]=2;
      			continue;
      		}
      		for(int j=0;j<2;j++){
      			if(ch[i][j]&&!ed[ch[i][j]]){
      				deg[ch[i][j]]++;
      			}
      		}
      	}
      	queue<int> q;
      	fl=0;
      	for(int i=0;i<=id;i++)if(!ed[i]&&!deg[i]){
      		dfs(i);
      	}
      	return fl;
      }
      int main(){
      	ios::sync_with_stdio(0);
      	cin.tie(0);
      	cin>>n;
      	string s;
      	for(int i=1;i<=n;i++){
      		cin>>s;
      		ins(s);
      	}
      	build();
      	if(solve())cout<<"TAK";
      	else cout<<"NIE";
      	return 0;
      }
      
      
      • 1

      信息

      ID
      4603
      时间
      1000ms
      内存
      512MiB
      难度
      8
      标签
      递交数
      66
      已通过
      10
      上传者