21.6.23 t3
阿新 • • 發佈:2021-06-24
tag:字尾樹
建出字尾樹,那麼答案一定是葉節點。
dfs字尾樹,每次走向的那條邊的字元一定大於所有其他邊的字元,就連一條邊過去。
最後看一看有沒有環。(傳遞閉包後自己大於自己)
複雜度 \(O(|S|^2n)\),\(S\) 為字符集,實際跑得挺快。
評測姬資料有問題,輸入得用while(~scanf)
#include<bits/stdc++.h> using namespace std; template<typename T> inline void Read(T &n){ char ch; bool flag=false; while(!isdigit(ch=getchar()))if(ch=='-')flag=true; for(n=ch^48;isdigit(ch=getchar());n=(n<<1)+(n<<3)+(ch^48)); if(flag)n=-n; } enum{ MAXN = 100005 }; struct node{ int son[12], fa, len, pos; #define son(x,opt) t[x].son[opt] #define fa(x) t[x].fa #define len(x) t[x].len #define pos(x) t[x].pos }t[MAXN<<1]; int node_cnt, prv; inline int insert(char v){ int x = ++node_cnt; len(x) = len(prv)+1; while(prv and !son(prv,v)) son(prv,v) = x, prv = fa(prv); if(!prv) fa(x) = 1; else{ int p = son(prv,v); if(len(p) == len(prv)+1) fa(x) = p; else{ int new_p = ++node_cnt; len(new_p) = len(prv)+1; fa(new_p) = fa(p); fa(p) = fa(x) = new_p; copy(t[p].son,t[p].son+12,t[new_p].son); while(prv and son(prv,v)==p) son(prv,v) = new_p, prv = fa(prv); } } return prv=x; } vector<int>to[MAXN<<1]; char a[MAXN]; int pos[MAXN]; char able[MAXN<<1]; inline void clear(){ for(int i=1; i<=node_cnt; i++) memset(t[i].son,0,sizeof t[i].son), fa(i) = len(i) = able[i] = 0, to[i].clear(); node_cnt = prv = 1; } void pre_dfs(int x){for(int v:to[x]) pre_dfs(v), pos(x) = pos(v);} int vis[12], tmpvis[12]; int cnt[12][12]; void dfs(int x){ if(!to[x].size()){ copy(vis,vis+12,tmpvis); for(int i=0; i<12; i++) for(int j=0; j<12; j++) if(tmpvis[j]>>i&1) tmpvis[j] or_eq tmpvis[i]; for(int i=0; i<12; i++) if(tmpvis[i]>>i&1) return; return able[x]=true, void(); } for(int v:to[x]){ char vv = a[pos(v)+len(x)]-'a'; for(int u:to[x]) if(v!=u){ char vu = a[pos(u)+len(x)]-'a'; vis[vv] |= 1<<vu; cnt[vv][vu]++; } dfs(v); for(int u:to[x]) if(v!=u){ char vu = a[pos(u)+len(x)]-'a'; cnt[vv][vu]--; if(!cnt[vv][vu]) vis[vv] ^= 1<<vu; } } } int main(){ // freopen("3.in","r",stdin); int T; Read(T); while(~scanf("%s",a+1)){ clear(); int n = strlen(a+1); for(int i=n; i; i--) pos[i] = insert(a[i]-'a'), pos(pos[i]) = i; for(int i=1; i<=node_cnt; i++) if(fa(i)) to[fa(i)].push_back(i); pre_dfs(1); dfs(1); for(int i=1; i<=n; i++) putchar(able[pos[i]]^48);puts(""); } return 0; }