后缀自动机(hdu4641多校联合)
来源:互联网 发布:编程不等于怎么表示 编辑:程序博客网 时间:2024/04/27 14:27
Online JudgeOnline ExerciseOnline TeachingOnline ContestsExercise AuthorF.A.Q
Hand In Hand
Online Acmers
Forum | Discuss
Statistical ChartsBest Coder beta
VIP | STD Contests
Virtual Contests
DIY | Web-DIY beta
Recent Contests
Total Submission(s): 660 Accepted Submission(s): 212
Hand In Hand
Online Acmers
Forum | Discuss
Statistical ChartsBest Coder beta
VIP | STD Contests
Virtual Contests
DIY | Web-DIY beta
Recent Contests
【比赛提醒】BestCoder 你报名了吗?(点击报名)
【科普】什么是BestCoder?如何参加?
【科普】什么是BestCoder?如何参加?
K-string
Time Limit: 4000/2000 MS (Java/Others) Memory Limit: 102400/131072 K (Java/Others)Total Submission(s): 660 Accepted Submission(s): 212
Problem Description
Given a string S. K-string is the sub-string of S and it appear in the S at least K times.It means there are at least K different pairs (i,j) so that Si,Si+1... Sj equal to this K-string. Given m operator or query:1.add a letter to the end of S; 2.query how many different K-string currently.For each query ,count the number of different K-string currently.
Input
The input consists of multiple test cases.
Each test case begins with a line containing three integers n, m and K(1<=n,K<=50000,1<=m<=200000), denoting the length of string S, the number of operator or question and the least number of occurrences of K-string in the S.
The second line consists string S,which only contains lowercase letters.
The next m lines describe the operator or query.The description of the operator looks as two space-separated integers t c (t = 1; c is lowercase letter).The description of the query looks as one integer t (t = 2).
Each test case begins with a line containing three integers n, m and K(1<=n,K<=50000,1<=m<=200000), denoting the length of string S, the number of operator or question and the least number of occurrences of K-string in the S.
The second line consists string S,which only contains lowercase letters.
The next m lines describe the operator or query.The description of the operator looks as two space-separated integers t c (t = 1; c is lowercase letter).The description of the query looks as one integer t (t = 2).
Output
For each query print an integer — the number of different K-string currently.
Sample Input
3 5 2abc21 a21 a2
Sample Output
011
题意:两种操作,1是添加字符,2是查询出现K次的不同的子串有多少个
思路:在线添加查询SAM,每次添加的时候顺便维护每个节点出现多少次,询问的时候直接输出就可以了,维护的原理就是根据后缀自动机的性质,父节点跟子节点有相同的后缀,但长度短,所以每次从最后一个节点沿Parent走一遍,经过的点肯定都要加上,然后容斥一下算出每次新加的有多少个
另外用指针真的很慢啊
#include<iostream>#include<cstdio>#include<cstring>#include<string>#include<vector>#include<algorithm>using namespace std;typedef long long LL;const int maxn=300010;const int SIGMA_SIZE=26;int N,M,K;LL ans;char s[maxn];struct SAM_Node{ SAM_Node *par,*next[SIGMA_SIZE]; int len,id,pos,cnt; SAM_Node(){} SAM_Node(int _len) { par=0; len=_len; cnt=0; memset(next,0,sizeof(next)); }};SAM_Node node[maxn*2],*root,*last;int SAM_size;SAM_Node *newSAM_Node(int len){ node[SAM_size]=SAM_Node(len); node[SAM_size].id=SAM_size; return &node[SAM_size++];}SAM_Node *newSAM_Node(SAM_Node *p){ node[SAM_size]=*p; node[SAM_size].id=SAM_size; return &node[SAM_size++];}void SAM_add(int x){ SAM_Node *p=last,*np=newSAM_Node(p->len+1); last=np; while(p&&!p->next[x]) { p->next[x]=np; p=p->par; } if(!p) np->par=root; else { SAM_Node *q=p->next[x]; if(q->len==p->len+1) np->par=q; else { SAM_Node *nq=newSAM_Node(q); nq->len=p->len+1; q->par=nq; np->par=nq; while(p&&p->next[x]==q) { p->next[x]=nq; p=p->par; } } } SAM_Node *tmp; for(tmp=last;tmp;tmp=tmp->par) { if(tmp->cnt==K)break; tmp->cnt++; if(tmp->cnt==K) { int num; if(!tmp->par)num=0; else num=tmp->par->len; ans=ans+(tmp->len)-num; break; } }}void SAM_init(){ SAM_size=0; root=last=newSAM_Node(0); node[0].pos=0;}void SAM_build(char *s){ SAM_init(); int len=strlen(s); for(int i=0;i<len;i++) SAM_add(s[i]-'a');}int main(){ int op; char t[5]; while(scanf("%d%d%D",&N,&M,&K)!=EOF) { scanf("%s",s); ans=0; SAM_build(s); while(M--) { scanf("%d",&op); if(op==1) { scanf("%s",t); SAM_add(t[0]-'a'); } else printf("%I64d\n",ans); } } return 0;}
0 0
- 后缀自动机(hdu4641多校联合)
- hdu4641-K-string(后缀自动机)
- 【后缀自动机-后缀树上的维护】hdu4641
- hdu4641 K-string,后缀自动机,并查集
- 多串后缀自动机(hdu4436)
- 【后缀自动机】【SAM】【自动机】【数据结构】后缀自动机理解(入门)
- 2017多校联合第六场String/hdu 6096 (tire tree/ac自动机)
- hdu5384 Danganronpa AC自动机 多校联合第八场
- 2015多校联合第八场hdu5384Danganronpa AC自动机
- hdu4416[多串后缀自动机]
- 后缀自动机(SAM)学习指南
- HDU 4622(后缀自动机)
- HDU 4436(后缀自动机)
- POJ 3415(后缀自动机)
- SPOJ LCS(后缀自动机)
- SPOJ LCS2(后缀自动机)
- SPOJ NSUBSTR(后缀自动机)
- SPOJ1812:LCS2 (后缀自动机)
- 写个简单的飞机游戏玩玩
- ubuntu之路
- 浅析 Linux 初始化 init 系统,第 3 部分: Systemd
- 第一次写CSDN博客
- ls -l 显示文件夹的大小错误
- 后缀自动机(hdu4641多校联合)
- numpy
- Powershell profile
- ubuntu双系统
- 多层地层和岩体3D表现及连续地形剖面的实现
- [LeetCode]113.Path Sum II
- Visio工具的跨线解决问题
- centos6.5升级vim到7.4
- [leetcode 60] Permutation Sequence