HDU 4641 SAM

来源:互联网 发布:jquery post提交 php 编辑:程序博客网 时间:2024/06/06 05:32


动态在尾部加入字符,统计相同字符串出现次数 >= k 得字符串有多少个。

0 0很显然用 SAM来做。 每次当这个节点出现了k次之后,就增加了  p->cnt -  p->f-cnt 得数目得子串

用cout竟然超时了。0 0.。。 哎。。换成printf才过掉。。坑于cout


#include <cstdio>#include <cstdlib>#include <iostream>using namespace std;const int MAX_NODES = 1006666;const int N = 755555;struct node{struct node* ch[26];struct node* f;int mx,cnt;void init(){memset(ch,0,sizeof(ch));f = 0; mx = 0 ; cnt = 0; }int calc(){return mx-f->mx;}}*root,*cur,*tail,pool[MAX_NODES];bool vis[MAX_NODES];void add(int c){node *p = tail, *np = cur++;np->init(); for( ; p && !p->ch[c] ;p=p->f) p->ch[c] = np;np->mx = tail->mx+1; tail = np ;if(!p) np->f = root;else if(p->mx+1 == p->ch[c]->mx) np->f = p->ch[c];else{node * q = p->ch[c] , *r = cur++;  *r = *q;  r->mx = p->mx+1;q->f = np->f = r;for(; p && p->ch[c] == q ; p=p->f) p->ch[c] = r;}}char s[N];int len;long long ans;int n,m,k;void cc(){node *p = tail;for( ; p != root && !vis[p-root]; p = p->f){if(p->cnt>=k) break; // 判断父亲节点是否已经计算过了。。p->cnt++;if(p->cnt>=k){ans += p->calc();}}}void suffix_auto_init(){int i;ans = 0;root = cur = tail = pool; cur++; root->init();for(i = 0; s[i] ;i++){add(s[i]-'a');cc();}len = i;}char ts[10];int main(){int q,vq;while(scanf("%d %d %d",&n,&m,&k)!=EOF){scanf("%s",s);suffix_auto_init();while(m--){scanf("%d",&vq);if(vq==2){printf("%I64d\n",ans);}else{scanf("%s",ts);add(ts[0]-'a');cc();}}}return 0;}


0 0
原创粉丝点击