SAM入门
学了两天,会了点皮毛,这里只放代码。
P3804
#include<iostream> #include<cstdio> #include<cmath> #include<ctime> #include<queue> #include<algorithm> #include<cstring> using namespace std; #define duke(i,a,n) for(register int i = a;i <= n;++i) #define lv(i,a,n) for(register int i = a;i >= n;--i) #define clean(a) memset(a,0,sizeof(a)) const int INF = 1 << 30; typedef long long ll; typedef double db; template <class T> void read(T &x) { char c; bool op = 0; while(c = getchar(), c < '0' || c > '9') if(c == '-') op = 1; x = c - '0'; while(c = getchar(), c >= '0' && c <= '9') x = x * 10 + c - '0'; if(op) x = -x; } template <class T> void write(T x) { if(x < 0) putchar('-'), x = -x; if(x >= 10) write(x / 10); putchar('0' + x % 10); } const int N = 1e6 + 5; struct node { int ch[27]; int len,fa; node() { clean(ch); len = 0; } }dian[N << 1]; int las = 1,tot = 1; int len; char s[N]; int buc[N << 1],siz[N << 1],pos[N << 1]; inline void add(int c) { int p = las;int np = las = ++tot; dian[np].len = dian[p].len + 1; for(;p && !dian[p].ch[c];p = dian[p].fa) dian[p].ch[c] = np; if(!p) dian[np].fa = 1; else { int q = dian[p].ch[c]; if(dian[q].len == dian[p].len + 1) dian[np].fa = q; else { int nq = ++tot; dian[nq] = dian[q]; dian[nq].len = dian[p].len + 1; dian[q].fa = dian[np].fa = nq; for(;p && dian[p].ch[c] == q;p = dian[p].fa) dian[p].ch[c] = nq; } } siz[np] = 1; } /*void add(int c) { int p=las;int np=las=++tot; dian[np].len=dian[p].len+1; for(;p&&!dian[p].ch[c];p=dian[p].fa)dian[p].ch[c]=np; if(!p)dian[np].fa=1;//以上为case 1 else { int q=dian[p].ch[c]; if(dian[q].len==dian[p].len+1)dian[np].fa=q;//以上为case 2 else { int nq=++tot;dian[nq]=dian[q]; dian[nq].len=dian[p].len+1; dian[q].fa=dian[np].fa=nq; for(;p&&dian[p].ch[c]==q;p=dian[p].fa)dian[p].ch[c]=nq;//以上为case 3 } } siz[las = np] = 1; }*/ inline int dfs() { int ret = 0; duke(i,1,tot) ++buc[dian[i].len]; duke(i,1,tot) buc[i] += buc[i - 1]; duke(i,1,tot) pos[buc[dian[i].len]--] = i; for(int i = tot;i;i--) { int now = pos[i]; siz[dian[now].fa] += siz[now]; if(siz[now] > 1) ret = max(ret,siz[now] * dian[now].len); } return ret; } int main() { scanf("%s",s); len = strlen(s); duke(i,0,len - 1) { add(s[i] - 'a'); } printf("%d\n",dfs()); return 0; }
SP1811
#include<iostream> #include<cstdio> #include<cmath> #include<ctime> #include<queue> #include<algorithm> #include<cstring> using namespace std; #define duke(i,a,n) for(register int i = a;i <= n;++i) #define lv(i,a,n) for(register int i = a;i >= n;--i) #define clean(a) memset(a,0,sizeof(a)) const int INF = 1 << 30; typedef long long ll; typedef double db; template <class T> void read(T &x) { char c; bool op = 0; while(c = getchar(), c < '0' || c > '9') if(c == '-') op = 1; x = c - '0'; while(c = getchar(), c >= '0' && c <= '9') x = x * 10 + c - '0'; if(op) x = -x; } template <class T> void write(T x) { if(x < 0) putchar('-'), x = -x; if(x >= 10) write(x / 10); putchar('0' + x % 10); } const int N = 250005; struct node { int fa,len; int ch[27]; node() { len = 0; clean(ch); } }dian[N << 1]; int tot = 1,las = 1,len1,len2; char s1[N],s2[N]; inline void add(int c) { int p = las;int np = las = ++tot; dian[np].len = dian[p].len + 1; for(;p && !dian[p].ch[c];p = dian[p].fa) dian[p].ch[c] = np; if(!p) dian[np].fa = 1; else { int q = dian[p].ch[c]; if(dian[q].len == dian[p].len + 1) dian[np].fa = q; else { int nq = ++tot; dian[nq] = dian[q]; dian[nq].len = dian[p].len + 1; dian[q].fa = dian[np].fa = nq; for(;p && dian[p].ch[c] == q;p = dian[p].fa) dian[p].ch[c] = nq; } } } inline int Max(int x,int y) { return x < y ? y : x; } inline int lcs(char *s) { int n = strlen(s),ret = 0; for(int i = 0,p = 1,l = 0;i < n;++i) { int c = s[i] - 'a'; if(dian[p].ch[c] != 0) l++,p = dian[p].ch[c]; else { for(;p && !dian[p].ch[c];p = dian[p].fa) ; if(!p) l = 0,p = 1; else { l = dian[p].len + 1; p = dian[p].ch[c]; } } ret = Max(ret,l); } return ret; } int main() { scanf("%s",s1); scanf("%s",s2); len1 = strlen(s1); len2 = strlen(s2); for(register int i = 0;i < len1;++i) { add(s1[i] - 'a'); } printf("%d\n",lcs(s2)); return 0; }
SP1812
#include<iostream> #include<cstdio> #include<cmath> #include<ctime> #include<queue> #include<algorithm> #include<cstring> using namespace std; #define duke(i,a,n) for(register int i = a;i <= n;++i) #define lv(i,a,n) for(register int i = a;i >= n;--i) #define clean(a) memset(a,0,sizeof(a)) const int INF = 1 << 30; typedef long long ll; typedef double db; template <class T> void read(T &x) { char c; bool op = 0; while(c = getchar(), c < '0' || c > '9') if(c == '-') op = 1; x = c - '0'; while(c = getchar(), c >= '0' && c <= '9') x = x * 10 + c - '0'; if(op) x = -x; } template <class T> void write(T x) { if(x < 0) putchar('-'), x = -x; if(x >= 10) write(x / 10); putchar('0' + x % 10); } const int N = 1e5 + 5; struct node { int fa,len; int ch[27]; node() { clean(ch); len = 0; } } dian[N << 1]; char s1[N],s2[N]; int las = 1,tot = 1; inline void add(int c) { int p = las; int np = las = ++tot; dian[np].len = dian[p].len + 1; for(; p && !dian[p].ch[c]; p = dian[p].fa) dian[p].ch[c] = np; if(!p) dian[np].fa = 1; else { int q = dian[p].ch[c]; if(dian[q].len == dian[p].len + 1) dian[np].fa = q; else { int nq = ++tot; dian[nq] = dian[q]; dian[nq].len = dian[p].len + 1; dian[q].fa = dian[np].fa = nq; for(; p && dian[p].ch[c] == q; p = dian[p].fa) dian[p].ch[c] = nq; } } } int pos[N << 1],buc[N << 1],Max[N << 1],Min[N << 1]; inline void dfs(char *s) { int n = strlen(s); for(int i = 0,p = 1,l = 0; i < n; ++i) { int c = s[i] - 'a'; for(; p && !dian[p].ch[c];) p = dian[p].fa,l = dian[p].len; if(!p) l = 0,p = 1; else { l ++; p = dian[p].ch[c]; Max[p] = max(Max[p],l); } } for(int i = tot; i >= 1; --i) { int now = pos[i],f = dian[now].fa; Max[f] = max(Max[f],min(Max[now],dian[f].len)); Min[now] = min(Min[now],Max[now]); Max[now] = 0; } } void sort() { duke(i,1,tot) ++buc[dian[i].len]; duke(i,1,tot) buc[i] += buc[i - 1]; duke(i,1,tot) pos[buc[dian[i].len] --] = i; } int main() { scanf("%s",s1); int len1 = strlen(s1); for(register int i = 0; i < len1; ++i) { add(s1[i] - 'a'); } sort(); memset(Min,0x3f,sizeof(Min)); clean(Max); while(scanf("%s",s2) != EOF) { dfs(s2); } int ans = 0; duke(i,1,tot) ans = max(ans,Min[i]); printf("%d\n",ans); return 0; }
P2852 [USACO06DEC]牛奶模式Milk Patterns
#include<iostream> #include<cstdio> #include<cmath> #include<ctime> #include<queue> #include<algorithm> #include<cstring> using namespace std; #define duke(i,a,n) for(register int i = a;i <= n;++i) #define lv(i,a,n) for(register int i = a;i >= n;--i) #define clean(a) memset(a,0,sizeof(a)) const int INF = 1 << 30; typedef long long ll; typedef double db; template <class T> void read(T &x) { char c; bool op = 0; while(c = getchar(), c < '0' || c > '9') if(c == '-') op = 1; x = c - '0'; while(c = getchar(), c >= '0' && c <= '9') x = x * 10 + c - '0'; if(op) x = -x; } template <class T> void write(T x) { if(x < 0) putchar('-'), x = -x; if(x >= 10) write(x / 10); putchar('0' + x % 10); } const int N = 2e4 + 5; struct node { int len,fa; int ch[27]; node() { clean(ch); len = 0; } }dian[N << 1]; int las = 1,tot = 1; int n,k; int x,pos[N << 1],siz[N << 1]; void add(int c) { int p = las;int np = las = ++tot; dian[np].len = dian[p].len + 1; siz[np] = 1; for(;p && !dian[p].ch[c];p = dian[p].fa) dian[p].ch[c] = np; if(!p) dian[np].fa = 1; else { int q = dian[p].ch[c]; if(dian[q].len == dian[p].len + 1) dian[np].fa = q; else { int nq = ++tot; dian[nq] = dian[q]; dian[nq].len = dian[p].len + 1; dian[q].fa = dian[np].fa = nq; for(;p && dian[p].ch[c] == q;p = dian[p].fa) dian[p].ch[c] = nq; } } } int dfs() { int ret = 0; for(int i = 1;i <= tot;i++) pos[i] = i; sort(pos + 1,pos + tot + 1,[=](int &a,int &b){return dian[a].len > dian[b].len;}); for(int i = 1;i <= tot;++i) { siz[dian[pos[i]].fa] += siz[pos[i]]; if(siz[pos[i]] >= k) { ret = max(ret,dian[pos[i]].len); } } return ret; } int main() { read(n);read(k); for(int i = 1;i <= n;++i) read(x),add(x); printf("%d\n",dfs()); return 0; }
P3975 [TJOI2015]弦论
#include<iostream> #include<cstdio> #include<cmath> #include<ctime> #include<queue> #include<algorithm> #include<cstring> using namespace std; #define duke(i,a,n) for(register int i = a;i <= n;++i) #define lv(i,a,n) for(register int i = a;i >= n;--i) #define clean(a) memset(a,0,sizeof(a)) const int INF = 1 << 30; typedef long long ll; typedef double db; template <class T> void read(T &x) { char c; bool op = 0; while(c = getchar(), c < '0' || c > '9') if(c == '-') op = 1; x = c - '0'; while(c = getchar(), c >= '0' && c <= '9') x = x * 10 + c - '0'; if(op) x = -x; } template <class T> void write(T x) { if(x < 0) putchar('-'), x = -x; if(x >= 10) write(x / 10); putchar('0' + x % 10); } const int N = 5e5 + 5; struct node { int len,fa; int ch[27]; }dian[N << 1]; char s[N]; int las = 1,tot = 1; int n,k,flg; int x,pos[N << 1],siz[N << 1],buc[N << 1],sum[N << 1]; void add(int c) { int p = las;int np = las = ++tot; dian[np].len = dian[p].len + 1; siz[np] = 1; for(;p && !dian[p].ch[c];p = dian[p].fa) dian[p].ch[c] = np; if(!p) dian[np].fa = 1; else { int q = dian[p].ch[c]; if(dian[q].len == dian[p].len + 1) dian[np].fa = q; else { int nq = ++tot; dian[nq] = dian[q]; dian[nq].len = dian[p].len + 1; dian[q].fa = dian[np].fa = nq; for(;p && dian[p].ch[c] == q;p = dian[p].fa) dian[p].ch[c] = nq; } } } inline void dfs() { for(int i = 1; i <= tot; ++i) ++buc[dian[i].len]; for(int i = 1; i <= tot; ++i) buc[i] += buc[i - 1]; for(int i = 1; i <= tot; ++i) pos[buc[dian[i].len]--] = i; for(int i = tot; i; --i) siz[dian[pos[i]].fa] += siz[pos[i]]; for(int i = 1; i <= tot; ++i) { if(!flg) sum[i] = siz[i] = 1; else sum[i] = siz[i]; } siz[1] = 0; for(int i = tot; i; --i) for(int j = 0; j < 26; ++j) if(dian[pos[i]].ch[j]) sum[pos[i]] += sum[dian[pos[i]].ch[j]]; } inline void print(int k) { if(sum[1] < k) { printf("-1\n"); return; } int now = 1; k -= siz[now]; while(k) { int c = 0; while(k > sum[dian[now].ch[c]]) { k -= sum[dian[now].ch[c++]]; } now = dian[now].ch[c]; putchar('a' + c); k -= siz[now]; } } int main() { scanf("%s",s); n = strlen(s); duke(i,0,n << 1) dian[i].len = 0,clean(dian[i].ch); duke(i,0,n - 1) add(s[i] - 'a'); read(flg);read(k); dfs(); print(k); puts(""); return 0; }
P4070 [SDOI2016]生成魔咒
#include<iostream> #include<cstdio> #include<cmath> #include<ctime> #include<queue> #include<algorithm> #include<cstring> #include<map> using namespace std; #define duke(i,a,n) for(register int i = a;i <= n;++i) #define lv(i,a,n) for(register int i = a;i >= n;--i) #define clean(a) memset(a,0,sizeof(a)) const int INF = 1 << 30; typedef long long ll; typedef double db; template <class T> void read(T &x) { char c; bool op = 0; while(c = getchar(), c < '0' || c > '9') if(c == '-') op = 1; x = c - '0'; while(c = getchar(), c >= '0' && c <= '9') x = x * 10 + c - '0'; if(op) x = -x; } template <class T> void write(T x) { if(x < 0) putchar('-'), x = -x; if(x >= 10) write(x / 10); putchar('0' + x % 10); } const int N = 2e5 + 5; struct node { int fa; ll len; map <int,int> ch; }dian[N << 1]; char s[N]; int las = 1,tot = 1; int n,k; ll ans = 0; int x; void add(int c) { int p = las;int np = las = ++tot; dian[np].len = dian[p].len + 1; for(;p && !dian[p].ch[c];p = dian[p].fa) dian[p].ch[c] = np; if(!p) dian[np].fa = 1,ans += dian[np].len; else { int q = dian[p].ch[c]; if(dian[q].len == dian[p].len + 1) dian[np].fa = q,ans += dian[np].len - dian[q].len; else { int nq = ++tot; dian[nq] = dian[q]; dian[nq].len = dian[p].len + 1; ans -= dian[q].len - dian[dian[q].fa].len; dian[q].fa = dian[np].fa = nq; ans += dian[nq].len - dian[dian[nq].fa].len; ans += dian[q].len - dian[nq].len; ans += dian[np].len - dian[nq].len; for(;p && dian[p].ch[c] == q;p = dian[p].fa) dian[p].ch[c] = nq; } } } int main() { read(n); while(n--) { int c; read(c); add(c); printf("%lld\n",ans); } return 0; }
只想找一个不会伤害我的人