• 「雅礼集训 2017 Day4」编码


    传送门

    嗯,根据(nekko)大佬的说法跑去搞(SAM)建后缀树,然后发现(Trie)就过了

    每个串最多有一个模糊字符,且只能是(0/1),那么考虑(2-sat)

    我们发现如果把所有字符串建成一颗(Trie),那么就可以前缀优化建图,因为每个点的祖先都是自己的一个前缀

    当然后缀树也可以做到,不过没必要

    #include<bits/stdc++.h>
    using namespace std;
    namespace red{
    #define ls(p) (p<<1)
    #define rs(p) (p<<1|1)
    #define mid ((l+r)>>1)
    #define y1 qwq 
    	inline int read()
    	{
    		int x=0;char ch,f=1;
    		for(ch=getchar();(ch<'0'||ch>'9')&&ch!='-';ch=getchar());
    		if(ch=='-') f=0,ch=getchar();
    		while(ch>='0'&&ch<='9'){x=(x<<1)+(x<<3)+ch-'0';ch=getchar();}
    		return f?x:-x;
    	}
    	const int N=3e6+10,inf=1<<30;
    	int n,m,siz;
    	char s[N];
    	int p[N],pre[N],f[N];
    	int head[N],cnt;
    	struct point
    	{
    		int nxt,to;
    		point(){}
    		point(const int &nxt,const int &to):nxt(nxt),to(to){}
    	}a[N<<2];
    	inline void link(int x,int y)
    	{
    		a[++cnt]=(point){head[x],y};head[x]=cnt;
    	}
    	struct Tire
    	{
    		vector<int> v[N];
    		int rt=1,sum=0,tot=1,son[N][2];
    		inline void insert(int n,int id)
    		{
    			int x=rt;
    			for(int i=1;i<=n;++i)
    			{
    				int k=s[i]-'0';
    				if(!son[x][k]) son[x][k]=++tot;
    				x=son[x][k];
    			}
    			v[x].push_back(id);
    		}
    		inline void dfs(int x)
    		{
    			int len=v[x].size();
    			for(int i=0;i<len;++i)
    			{
    				p[++sum]=v[x][i];
    				pre[p[sum]]=++siz;
    				f[pre[p[sum]]]=++siz;
    				f[siz]=pre[p[sum]];
    				//p 选了 fp没选
    				//pre 选了 fpre没选 
    				link(p[sum],pre[p[sum]]);
    				//这个选了,这个及之前选了 
    				link(f[pre[p[sum]]],f[p[sum]]);
    				//这个及之前不选,这个不选 
    				if(sum!=1)
    				{
    					link(pre[p[sum-1]],pre[p[sum]]);
    					//上一个之前选了,这个及之前选了 
    					link(f[pre[p[sum]]],f[pre[p[sum-1]]]);
    					//这个及之前不选,上一个之前不选 
    					link(pre[p[sum-1]],f[p[sum]]);
    					//上一个及之前选了,这个不选 
    					link(p[sum],f[pre[p[sum-1]]]);
    					//选这个,上一个及之前不选 
    				}
    			}
    			if(son[x][0]) dfs(son[x][0]);
    			if(son[x][1]) dfs(son[x][1]);
    			sum-=len;
    		}
    	}T;
    	int dfn[N],low[N],st[N],col[N];
    	int idx,top,num;
    	inline void tarjan(int now)
    	{
    		dfn[now]=low[now]=++idx;
    		st[++top]=now;
    		for(int i=head[now];i;i=a[i].nxt)
    		{
    			int t=a[i].to;
    			if(!dfn[t])
    			{
    				tarjan(t);
    				low[now]=min(low[now],low[t]);
    			}
    			else if(!col[t]) low[now]=min(low[now],dfn[t]);
    		}
    		if(dfn[now]==low[now])
    		{
    			col[now]=++num;
    			while(st[top]!=now) col[st[top--]]=num;
    			--top;
    		}
    	}
    	inline void main()
    	{
    		n=read();siz=n;
    		for(int i=1;i<=n;++i)
    		{
    			scanf("%s",s+1);
    			int k=0,len=strlen(s+1);
    			for(int j=1;j<=len;++j) if(s[j]=='?') k=j;
    			f[i]=++siz;f[siz]=i;
    			if(k)
    			{
    				s[k]='0';T.insert(len,f[i]);
    				s[k]='1';T.insert(len,i);
    			}
    			else link(f[i],i),T.insert(len,i);
    		}
    		T.dfs(T.rt);
    		for(int i=1;i<=siz;++i)
    			if(!dfn[i]) tarjan(i);
    		for(int i=1;i<=siz;++i)
    			if(col[i]==col[f[i]]) return(void)puts("NO");
    		puts("YES");
    	}
    }
    signed main()
    {
    	//freopen("haha.in","r",stdin);
    	red::main();
    	return 0;
    }
    
  • 相关阅读:
    OC和Swift中的UITabBar和UINaviGationBar的适配 [UITabbar在IPad中的适配]
    <iOS开发>之App上架流程(2017)
    iOS--LaunchImage启动页设置及问题解决
    去掉ambiguous expansion of macro警告
    iosapp开发者账号信息管理
    开发一个 app 有多难?
    Android SDK下载安装及配置教程
    抽象类和借口的区别
    array,vertor,arraylist,hashable,hashmap等几个易混淆概念的区别
    判断Set里的元素是否重复、==、equals、hashCode方法研究-代码演示
  • 原文地址:https://www.cnblogs.com/knife-rose/p/12708949.html
走看看 - 开发者的网上家园