zoukankan      html  css  js  c++  java
  • 「雅礼集训 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;
    }
    
  • 相关阅读:
    nextcloud环境搭建及部署
    docker容器内访问宿主机,访问不通 错误:Host is unreachable
    记录一下SQL的行行比较
    记录一次nginx平滑升级
    letsencrypt免费SSL证书自动续期
    守护进程因echo挂掉的原因,以及重定向标准输入、标准输出和标准错误
    openresty lua-nginx-module模块中文文档
    nginx localhost的坑
    PHP7 MongoDb的操作类
    tomcat 性能检测
  • 原文地址:https://www.cnblogs.com/knife-rose/p/12708949.html
Copyright © 2011-2022 走看看