【2SAT+Trie】Gym101190B [NEERC2016] Binary Code


【タイトル】Gymはいくつかのバイナリ符号化を与え、各符号化はせいぜい1つの位置が何なのか分からない.他の符号化のプレフィックスである符号化が1つもないように補完符号化方式があるかどうかを尋ねる.n , ∑ ∣ s ∣ ≤ 5 × 1 0 5 n,\sum|s|\leq 5\times 10^5 n,∑∣s∣≤5×105
【解題の考え方】2つのうちの選択は実際には2-SATtext{2-SAT}2-SATモデルである.しかし、私たちが暴力的に図を作ると涼しくなるので、Trietext{Trie}Trieを使って図を作るのを補助することを考えて、すべての列を1本のTrietext{Trie}Trieの木を建てて、いずれかの根から葉への経路に相当して多くの点があれば、接頭辞で図を最適化することができます.そしてなくなったの?簡単だね
【参考コード】
#include
using namespace std;

const int N=5e6+10;

namespace Trie
{
	int sz,pos[N],fa[N],ch[N][2];
	void insert(char *s,int len,int p)
	{
		int now=0;
		for(int i=0;i<len;++i)
		{
			int x=s[i]^48;
			if(!ch[now][x]) ch[now][x]=++sz,fa[sz]=now;
			now=ch[now][x];
		}
		pos[p]=now;
	}
}
using namespace Trie;


namespace Graph
{
	int tot,top,scc,ind;
	int head[N],dfn[N],low[N],st[N],ins[N],bl[N];
	struct Tway{int v,nex;}e[N<<1];
	void add(int u,int v)
	{
		//printf("%d %d
",u,v);
e[++tot]=(Tway){v,head[u]};head[u]=tot; } void tarjan(int x) { //printf("%d
",x);
dfn[x]=low[x]=++ind;ins[x]=1;st[++top]=x; for(int i=head[x];i;i=e[i].nex) { int v=e[i].v; if(!dfn[v]) tarjan(v),low[x]=min(low[x],low[v]); else if(ins[v]) low[x]=min(low[x],dfn[v]); } if(dfn[x]^low[x]) return; //printf("%d
",top);
int u=0;++scc;do{u=st[top--];ins[u]=0;bl[u]=scc;}while(top && u!=x); } } using namespace Graph; namespace DreamLolita { int n,fg[N]; char s[N]; vector<string>S; vector<int>vec[N]; void solution() { scanf("%d",&n); for(int i=1;i<=n;++i) { scanf("%s",s);fg[i]=-1; int len=strlen(s);string now=""; for(int j=0;j<len;++j) { now+=s[j]; if(s[j]=='?') fg[i]=j; } S.push_back(now); if(!~fg[i]) { add(i<<1,i<<1|1);insert(s,len,i<<1|1);pos[i<<1]=pos[i<<1|1]; } else { s[fg[i]]='0';insert(s,len,i<<1);s[fg[i]]='1';insert(s,len,i<<1|1); } } int sum=(n<<1|1)+2; for(int i=1;i<=sz;++i) add(sum+(fa[i]<<1),sum+(i<<1)),add(sum+(i<<1|1),sum+(fa[i]<<1|1)); for(int i=2;i<=(n<<1|1);++i) { vec[pos[i]].push_back(i); if(ch[pos[i]][0]) add(i,sum+(ch[pos[i]][0]<<1)); if(ch[pos[i]][1]) add(i,sum+(ch[pos[i]][1]<<1)); add(i,sum+(fa[pos[i]]<<1|1));add(sum+(pos[i]<<1),i^1);add(sum+(pos[i]<<1|1),i^1); } sum+=(sz<<1|1)+2; for(int i=1;i<=sz;++i) { if(!vec[i].size()) continue; add(vec[i][0],sum);add(sum+1,vec[i][0]^1); for(int j=1;j<(int)vec[i].size();++j) { add(sum+(j<<1|1),sum+((j-1)<<1|1));add(sum+((j-1)<<1),sum+(j<<1)); add(vec[i][j],sum+(j<<1));add(sum+(j<<1|1),vec[i][j]^1); add(vec[i][j],sum+((j-1)<<1|1));add(sum+((j-1)<<1),vec[i][j]^1); } sum+=((int)vec[i].size()<<1|1)+2; } for(int i=1;i<=sum;++i) if(!dfn[i]) tarjan(i); //for(int i=1;i<=sum;++i) printf("%d ",bl[i]); puts(""); for(int i=1;i<=n;++i) if(bl[i<<1]==bl[i<<1|1]) {puts("NO");return;} puts("YES"); for(int i=1;i<=n;++i) { if(~fg[i]) S[i-1][fg[i]]=bl[i<<1|1]<bl[i<<1]?'1':'0'; int len=S[i-1].length(); for(int j=0;j<len;++j) putchar(S[i-1][j]); puts(""); } } } int main() { freopen("binary.in","r",stdin); freopen("binary.out","w",stdout); DreamLolita::solution(); return 0; }