题目链接:https://vjudge.net/contest/31226#problem/A
题意:给你两个字符串,问你两个字符串最长的公共字串有多长。
是后缀自动机的模板题(看了下后缀自动机,感觉半懂半不懂,做做模板题,理解下,再继续做)
开始忘了初始化=。=,然后一直T,哇,这个错不能再犯了。
/** @xigua */ #include <stdio.h> #include <cmath> #include <iostream> #include <algorithm> #include <vector> #include <stack> #include <cstring> #include <queue> #include <set> #include <string> #include <map> #include <climits> #define PI acos(-1) #define rep(a,b,c) for(int (a)=(b); (a)<(c); ++(a)) #define drep(a,b,c) for(int (a)=(b); (a)>(c); --(a)) #define CLR(x) memset(x, 0, sizeof(x)) #define sf scanf #define pf printf using namespace std; typedef long long ll; typedef double db; const int maxn = 250000 + 1000; const int ma = 1e5 + 1000; const int mod = 1e9 + 7; const int INF = 1e8 + 5; const ll inf = 1e17 + 5; const db eps = 1e-6; const int MAXN = 2e5+1e3; struct SAM{ int ch[maxn<<1][26]; int fa[maxn<<1], len[maxn<<1]; int cnt, last, root; void init() { root=1; memset(ch, 0, sizeof(ch)); memset(fa, 0, sizeof(fa)); last=cnt=root; } void add(int c) { int p=last, np=last=++cnt; len[np]=len[p]+1; while(!ch[p][c] && p) { ch[p][c]=np; p=fa[p]; } if (p==0) fa[np]=1; else { int q = ch[p][c]; if(len[p] + 1 == len[q]) { fa[np] = q; } else { int nq = ++cnt; len[nq] = len[p] + 1; memcpy(ch[nq], ch[q], sizeof ch[q]); fa[nq] = fa[q]; fa[q] = fa[np] = nq; while(ch[p][c] == q && p) { ch[p][c] = nq; p = fa[p]; } } } } int find(char *s) { int p=root, l=0, c=0; int lenn=strlen(s); for(int i = 0; i < lenn; i++) { if(ch[p][s[i] - 'a']) { p = ch[p][s[i] - 'a']; c++; } else { while(p&&!ch[p][s[i]-'a']) p=fa[p]; if (!p) c=0, p=1; else c=len[p]+1, p=ch[p][s[i]-'a']; } l = max(l, c); } printf("%d ", l); } }sam; char s[maxn]; void solve() { scanf("%s", s); int lenn=strlen(s); sam.init(); for (int i=0; i<lenn; i++) { sam.add(s[i]-'a'); } scanf("%s", s); sam.find(s); } int main() { int t = 1, cas = 1; //freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); //scanf("%d", &t); while(t--) { // printf("Case %d: ", cas++); solve(); } return 0; }
做题竟然T了,我的板子不行啊
下面是个新板子
/** @xigua */ #include <stdio.h> #include <cmath> #include <iostream> #include <algorithm> #include <vector> #include <stack> #include <cstring> #include <queue> #include <set> #include <string> #include <map> #include <climits> #define PI acos(-1) #define rep(a,b,c) for(int (a)=(b); (a)<(c); ++(a)) #define drep(a,b,c) for(int (a)=(b); (a)>(c); --(a)) #define CLR(x) memset(x, 0, sizeof(x)) #define sf scanf #define pf printf using namespace std; typedef long long ll; typedef double db; const int maxn = 1e5 + 1000; const int ma = 1e5 + 1000; const int mod = 1e9 + 7; const int INF = 1e8 + 5; const ll inf = 1e17 + 5; const db eps = 1e-6; const int MAXN = 2e5+1e3; char pool[MAXN]; struct Str{ int st, len; }str[MAXN]; struct state { int len, pre, ch[26]; }; struct SAM { int sz, last; state st[MAXN]; state& operator[] (int x) { return st[x]; } void clear(int x) { CLR(st[x].ch); } void init() { sz=1, last=0; st[0].len=0, st[0].pre=-1; clear(0); } void add(int c) { int cur=sz++, p; clear(cur); st[cur].len=st[last].len+1; for(p=last; p!=-1&&!st[p].ch[c]; p=st[p].pre) st[p].ch[c]=cur; if(p==-1) st[cur].pre=0; else { int q=st[p].ch[c]; if(st[q].len==st[p].len+1) st[cur].pre=q; else { int clone=sz++; st[clone]=st[q]; st[clone].len=st[p].len+1; st[cur].pre=st[q].pre=clone; for(; p!=-1&&st[p].ch[c]==q; p=st[p].pre) st[p].ch[c]=clone; } } last=cur; } int find(string t) {//查询lcs int now=0, l=0, ans=0; int len=t.length(); for (int i=0; i<len; i++) { while(now&&!st[now].ch[t[i]-'a']) { now=st[now].pre; l=st[now].len; } if(st[now].ch[t[i]-'a']) { ++l; now=st[now].ch[t[i]-'a']; } ans=max(l, ans); } return ans; } } sam; string a[maxn]; bool check(int sel, int n) { for (int i=0; i<n; i++) { if (i!=sel) { if (sam.find(a[i])!=a[i].length()) return 0; } } return true; } char ans[maxn]; void solve() { int n; scanf("%d", &n); str[0].st=0; int sel=0, maxx=0; for (int i=0; i<n; i++) { scanf("%s", pool); int len=strlen(pool); if (len>maxx) { maxx=len; sel=i; } a[i]=string(pool); } sam.init(); int len=a[sel].length(); for (int i=0; i<len; i++) sam.add(a[sel][i]-'a'); for (int i=0; i<len; i++) ans[i]=a[sel][i]; if(check(sel,n)) { int l=a[sel].length(); for (int i=0; i<len; i++) printf("%c", ans[i]); puts(""); } else puts("No"); } int main() { int t = 1, cas = 1; //freopen("in.txt", "r", stdin); // freopen("out.txt", "w", stdout); scanf("%d", &t); while(t--) { // printf("Case %d: ", cas++); solve(); } return 0; }
拓扑排序
/** @xigua */ #include <cstdio> #include <cmath> #include <iostream> #include <algorithm> #include <vector> #include <stack> #include <cstring> #include <queue> #include <set> #include <string> #include <map> #include <climits> #define PI acos(-1) using namespace std; typedef long long ll; typedef double db; const int maxn = 200000 + 5; const int mod = 1e9 + 7; const int INF = 1e8 + 5; const ll inf = 1e15 + 5; const db eps = 1e-6; char s[maxn]; int Min[maxn<<1], Max[maxn<<1]; int ch[maxn<<1][26]; int fa[maxn<<1]; int len[maxn<<1]; int cnt, last; int c[maxn<<1], pt[maxn<<1]; void init() { memset(ch, 0, sizeof(ch)); memset(fa, 0, sizeof(fa)); memset(Min, INF, sizeof(Min)); memset(pt, 0, sizeof(pt)); memset(c, 0, sizeof(c)); last=cnt=1; } void add(int c) { int p = last, np = last = ++cnt; Min[np]=len[np] = len[p] + 1; while(!ch[p][c] && p) { ch[p][c] = np; p = fa[p]; } if(p == 0) fa[np] = 1; else { int q = ch[p][c]; if(len[p] + 1 == len[q]) { fa[np] = q; } else { int nq = ++cnt; len[nq] = len[p] + 1; memcpy(ch[nq], ch[q], sizeof ch[q]); fa[nq] = fa[q]; fa[q] = fa[np] = nq; while(ch[p][c] == q && p) { ch[p][c] = nq; p = fa[p]; } } } } void solve() { scanf("%s", s); int lenn = strlen(s); init(); for(int i = 0; i < lenn; i++) { add(s[i] - 'a'); } for (int i=1; i<=cnt; i++) c[len[i]]++; for (int i=1; i<=cnt; i++) c[i]+=c[i-1]; for (int i=cnt; i>=1; i--) pt[c[len[i]]--]=i; while(~scanf("%s", s)) { memset(Max, 0, sizeof(Max)); lenn = strlen(s); int p = 1; int c = 0; for(int i = 0; i < lenn; i++) { if(ch[p][s[i] - 'a']) { p = ch[p][s[i] - 'a']; c++; } else { while(p&&!ch[p][s[i]-'a']) p=fa[p]; if (!p) c=0, p=1; else c=len[p]+1, p=ch[p][s[i]-'a']; } Max[p]=max(Max[p], c); } for (int i=cnt; i>=1; i--) { p=pt[i]; if (Max[p]) Max[fa[p]]=len[fa[p]]; } for (int i=1; i<=cnt; i++) Min[i]=min(Min[i], Max[i]); } int ans=0; for (int i=1; i<=cnt; i++) ans = max(ans, Min[i]); printf("%d ", ans); } int main() { int t = 1; //freopen("in.txt", "r", stdin); // scanf("%d", &t); while(t--) solve(); return 0; }