2 条题解
-
-1
你说得对,但 AC 自动机相当好用。
数据结构,没有思维,只有硬来。
code
#include<bits/stdc++.h> using namespace std; const int N = 1e6+10; const int M = 510; int _; int t[N][30]; int fail[N]; int n; string s[M]; int ed[M],sum[N]; int tot; vector<int> e[N]; int ins(string s); void clean(int pos); void clear(); void build(); void build_tree(); void dfs(int x); void query(string s); int ins(string s) { int u=0; for(auto i:s) { int p=i-'a'+1; if(!t[u][p]) { t[u][p]=++tot; clean(tot); } u=t[u][p]; } return u; } void solve() { cin>>n; tot=0;clean(0); for(int i=1;i<=n;i++) { cin>>s[i]; ed[i]=ins(s[i]); } build(); build_tree(); for(int i=n;i;i--) { clear(); query(s[i]); dfs(0); for(int j=1;j<=i;j++) { if(!sum[ed[j]]) { cout<<i<<'\n'; return; } } } cout<<-1<<'\n'; } int main() { cin>>_; while(_--) solve(); return 0; } void clean(int pos) { for(int i=1;i<=26;i++) t[pos][i]=0; fail[pos]=0; } void clear() { for(int i=0;i<=tot;i++) sum[i]=0; } void build() { queue<int> q; for(int i=1;i<=26;i++) if(t[0][i]) q.push(t[0][i]); while(q.size()) { int u=q.front(); q.pop(); for(int i=1;i<=26;i++) { if(t[u][i]) { fail[t[u][i]]=t[fail[u]][i]; q.push(t[u][i]); } else { t[u][i]=t[fail[u]][i]; } } } } void query(string s) { int u=0; for(auto i:s) { int c=i-'a'+1; u=t[u][c]; sum[u]++; } } void dfs(int x) { for(auto i:e[x]) { dfs(i); sum[x]+=sum[i]; } } void build_tree() { for(int i=0;i<=tot;i++) e[i].clear(); for(int i=1;i<=tot;i++) { e[fail[i]].push_back(i); // cout<<fail[i]<<' '<<i<<'\n'; } }
信息
- ID
- 167
- 时间
- 1000ms
- 内存
- 256MiB
- 难度
- 6
- 标签
- (无)
- 递交数
- 32
- 已通过
- 11
- 上传者