SAM入门
Posted dukelv
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了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 ",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 ",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 ",ans); return 0; }
以上是关于SAM入门的主要内容,如果未能解决你的问题,请参考以下文章
SAM命令失败:ImportError:无法导入名称AliasedEventEmitter
Cg入门20:Fragment shader - 片段级模型动态变色(实现汽车动态换漆)