[Learning] SAM
来源:互联网 发布:薛定谔的猫 知乎 编辑:程序博客网 时间:2024/06/04 17:47
From cxlove
资料
http://fanhq666.blog.163.com/blog/static/8194342620123352232937/
题目
http://www.spoj.pl/problems/NSUBSTR/
这题基本上就是套个木板T_T 。 借鉴的cxlove 和 UESTC 神奇的 后缀三兄弟 Orz
cxlove mua ~
const int N = 250009;namespace SAM{const int CHAR = 26;const int LEN = N << 1;struct SAM_Node{ SAM_Node *fa , *son[CHAR]; int len , id , pos , g; SAM_Node(){} SAM_Node(int _len){ g = 0; fa = 0; len = _len; RST(son); }};SAM_Node node[LEN << 1] , *root , *last;int SAM_size;SAM_Node * newNode(int len){ node[SAM_size] = SAM_Node(len); node[SAM_size].id = SAM_size; return &node[SAM_size++];}SAM_Node *newNode(SAM_Node * p){ node[SAM_size] = *p; node[SAM_size].id = SAM_size; return &node[SAM_size++];}void init(){ SAM_size = 0; root = last = newNode(0); node[0].pos = 0;}void add(int x , int len){ SAM_Node *p = last , *np = newNode(p -> len + 1); np -> pos = len; last = np; for( ; p && !p -> son[x] ; p = p -> fa) p -> son[x] = np; if (!p){ np -> fa = root; return; } SAM_Node *q = p -> son[x]; if (q -> len == p -> len + 1){ np -> fa = q; return; } SAM_Node * nq = newNode(q); nq -> len = p -> len + 1; q -> fa = nq; np -> fa = nq; for ( ; p && p -> son[x] == q ; p = p -> fa) p -> son[x] = nq;}void build(char * s){ init(); int len = strlen(s); REP(i , len) add(s[i] - 'a' , i + 1);}}using namespace SAM;char str[N];int dp[N] , n , topocnt[N];SAM_Node *topsam[LEN];void solve(){ n = strlen(str); build(str); RST(topocnt); REP(i , SAM_size) topocnt[node[i].len] ++; REP_1(i , n) topocnt[i] += topocnt[i - 1]; REP(i , SAM_size) topsam[ -- topocnt[node[i].len] ] = &node[i]; REP(i , n) (root = root -> son[str[i] - 'a']) -> g++; RST(dp); for (int i = SAM_size - 1 ; i > 0 ; i--){ checkMax(dp[ topsam[i] -> len ] , topsam[i] -> g); if (topsam[i] -> fa) topsam[i] -> fa -> g += topsam[i] -> g; } for (int i = n - 1 ; i > 0 ; i--) checkMax(dp[i] , dp[i + 1]); REP_1(i , n) printf("%d\n" , dp[i]);}int main(){ while(~scanf("%s" , str)) solve();}
http://www.spoj.pl/problems/LCS/
const int N = 250009;const int CHAR = 26;namespace SAM{ struct Node{ Node * fa , *next[CHAR]; int len , id , pos; Node(){} Node(int _len){ fa = 0; len = _len; RST(next); } }; Node node[N << 1] , *root , *last; int size; Node * newnode(int len){ node[size] = Node(len); node[size].id = size; return &node[size++]; } Node * newnode(Node * p){ node[size] = *p; node[size].id = size; return &node[size++]; } void init(){ size = 0; root = last = newnode(0); node[0].pos = 0; } void add(int x , int len){ Node *p = last , *np = newnode(p -> len + 1); np -> pos = len; last = np; for( ; p && !p -> next[x] ; p = p -> fa) p -> next[x] = np; if (!p){ np -> fa = root; return; } Node *q = p -> next[x]; if (q -> len == p -> len + 1){ np -> fa = q; return; } Node * nq = newnode(q); nq -> len = p -> len + 1; q -> fa = nq; np -> fa = nq; for( ; p && p -> next[x] == q ; p = p -> fa) p -> next[x] = nq; } void build(char * s){ init(); int l = strlen(s); REP(i , l) add(s[i] - 'a' , i + 1); }}using namespace SAM;char str[N] , s[N];int ans , l , n , topcnt[N];Node* topo[N << 1] , *now;void solve(){ n = strlen(str); build(str); RST(topcnt); REP(i , size) topcnt[node[i].len]++; REP_1(i , n) topcnt[i] += topcnt[i - 1]; REP(i , size) topo[ -- topcnt[node[i].len] ] = &node[i]; n = strlen(s); ans = 0 , l = 0; now = root; REP(i , n){ int x = s[i] - 'a'; if(now -> next[x]){ l++; now = now -> next[x]; } else{ while(now && now -> next[x] == NULL) now = now -> fa; if (!now){ l = 0; now = root; } else{ l = now -> len + 1; now = now -> next[x]; } } checkMax(ans , l); } OT(ans);}int main(){ while(~scanf("%s%s" , str , s)) solve();}
http://www.spoj.pl/problems/LCS2/
const int N = 100009;const int CHAR = 26;namespace SAM{ struct Node{ Node * fa , *next[CHAR]; int len , id , pos; int curlen , minlen; Node(){} Node(int _len){ fa = 0; len = _len; RST(next); } }; Node node[N << 1] , *root , *last; int size; Node * newnode(int len){ node[size] = Node(len); node[size].id = size; return &node[size++]; } Node * newnode(Node * p){ node[size] = *p; node[size].id = size; return &node[size++]; } void init(){ size = 0; root = last = newnode(0); node[0].pos = 0; } void add(int x , int len){ Node *p = last , *np = newnode(p -> len + 1); np -> pos = len; last = np; for( ; p && !p -> next[x] ; p = p -> fa) p -> next[x] = np; if (!p){ np -> fa = root; return; } Node *q = p -> next[x]; if (q -> len == p -> len + 1){ np -> fa = q; return; } Node * nq = newnode(q); nq -> len = p -> len + 1; q -> fa = nq; np -> fa = nq; for( ; p && p -> next[x] == q ; p = p -> fa) p -> next[x] = nq; } void build(char * s){ init(); int l = strlen(s); REP(i , l) add(s[i] - 'a' , i + 1); }}using namespace SAM;char str[N];int ans , l , n , topcnt[N];Node* topo[N << 1] , *now;void solve(){ n = strlen(str); build(str); RST(topcnt); REP(i , size) topcnt[node[i].len]++; REP_1(i , n) topcnt[i] += topcnt[i - 1]; for (int i = size - 1 ; i >= 0 ; --i) topo[ -- topcnt[node[i].len] ] = &node[i]; REP(i , size){ topo[i] -> minlen = topo[i] -> len; } while(~scanf("%s" , str)){ REP(i , size) topo[i] -> curlen = 0; int len = 0; now = root; REP_C(i , strlen(str)){// OT(str[i]); int x = str[i] - 'a'; while(now -> fa && now -> next[x] == NULL) now = now -> fa , len = now -> len; if(now -> next[x]){ len++; now = now -> next[x]; checkMax(now -> curlen , len); } else{ len = 0; now = root; } } for (int i = size - 1 ; i >= 0 ; --i){ now = topo[i]; checkMin(now -> minlen , now -> curlen); if (now -> fa) checkMax(now -> fa -> curlen , now -> curlen); } } ans = 0; for (int i = 0 ; i < size ; ++i) checkMax(ans , node[i].minlen); OT(ans);}int main(){ scanf("%s" , str); solve();}
http://www.spoj.pl/problems/SUBLEX/
http://acm.hdu.edu.cn/showproblem.php?pid=4436
http://acm.hdu.edu.cn/showproblem.php?pid=4416
http://acm.hdu.edu.cn/showproblem.php?pid=4270
http://codeforces.com/contest/235/problem/C
- [Learning] SAM
- sam
- SAM
- SAM
- SAM
- sam初识+sam详解
- sam初识+sam详解
- PSAM & SAM
- PSAM/SAM
- 注册表 SAM
- PSAM SAM
- PSAM/SAM
- SAM模板
- Learning
- learning
- learning
- learning
- learning
- 用正则表达式验证用户名密码
- SGU 253. Theodore Roosevelt
- 简单工厂模式及工厂模式
- 建立CE 连接
- C语言:sizeof(结构体)
- [Learning] SAM
- Java中两种字符串初始化方法的区别
- C语言实现出入栈操作
- chapter 2.1: 什么是windows Driver
- C#操作Word (1)Word对象模型
- struts2与ActionContext
- 存储过程加密
- 怎样解密加密的存储过程
- 基于Android小巫新闻客户端开发---显示新闻详细内容UI设计