HDU 4641 至少出现K次本质不同子串数:后缀自动机
2017-09-22 00:19
495 查看
题意:先给出一个串,然后有若干操作。操作1:在结尾续上一个新字符。操作2:查询至少出现了K次的,本质不同的子串个数。
题解:SAM裸题,插入一个新的字符之后,就暴力在parent上转移++,但是也不能那么暴力,我们知道parent链上的num是单调增的,当遇到一个num>=k的点就不需要再继续走了,因为前边的肯定统计到答案里边了。
Code:
题解:SAM裸题,插入一个新的字符之后,就暴力在parent上转移++,但是也不能那么暴力,我们知道parent链上的num是单调增的,当遇到一个num>=k的点就不需要再继续走了,因为前边的肯定统计到答案里边了。
Code:
#include<bits/stdc++.h> using namespace std; const int maxn = 25e4+1000; char s[maxn]; int len,k,n,m; char temp[5]; struct SAM{ int last,cnt,nxt[maxn*2][26],fa[maxn*2],l[maxn*2],num[maxn*2]; int ans; void init(){ last = cnt=1; memset(nxt[1],0,sizeof nxt[1]); fa[1]=l[1]=num[1]=0; ans=0; } int inline newnode(){ cnt++; memset(nxt[cnt],0,sizeof nxt[cnt]); fa[cnt]=l[cnt]=num[cnt]=0; return cnt; } void add(int c){ int p = last; int np = newnode(); last = np; l[np] =l[p]+1; while (p&&!nxt[p][c]){ nxt[p][c] = np; p = fa[p]; } if (!p){ fa[np] =1; }else{ int q = nxt[p][c]; if (l[q]==l[p]+1){ fa[np] =q; }else{ int nq = newnode(); memcpy(nxt[nq],nxt[q],sizeof nxt[q]); fa[nq] =fa[q]; num[nq] = num[q]; l[nq] = l[p]+1; fa[np] =fa[q] =nq; while (nxt[p][c]==q){ nxt[p][c]=nq; p = fa[p]; } } } int temp = last; while (temp){ if (num[temp]>=k){ break; } num[temp]++; if (num[temp]==k){ ans+=l[temp]-l[fa[temp]]; } temp = fa[temp]; } } }sam; int main(){ while (scanf("%d%d%d",&n,&m,&k)!=EOF){ scanf("%s",s); len = strlen(s); sam.init(); for (int i=0;i<len;i++){ sam.add(s[i]-'a'); } while (m--){ int flag; scanf("%d",&flag); if (flag==1){ scanf("%s",temp); sam.add(temp[0]-'a'); }else{ printf("%d\n",sam.ans); } } } return 0; }
相关文章推荐
- hdu 4416 后缀自动机 求一个字符串中出现的不同子串的个数(去除一些其他字符串的子串)
- hdu 4622 求区间不同子串数 后缀数组|后缀自动机|字符串hash
- 2017沈阳网络赛 1001 HDU 6194 string string string(后缀自动机 出现k次的子串个数)
- hdu 4416 后缀自动机 问在S中有多少个不同子串满足它不是s1~sn中任意一个字符串的子串
- HDU 4622 Reincarnation(SAM 后缀自动机 求子串的不同子串个数)
- HDU 6194 String String String 后缀数组 正好出现K次的子串个数 CSU1632 至少出现2次的子串个数
- 后缀自动机 重复旋律 5(求所有本质不同的子串)
- HDU 4622 Reincarnation (查询一段字符串的不同子串个数,后缀自动机)
- HDU 4622 Reincarnation (查询一段字符串的不同子串个数,后缀自动机)
- HDU 4641 K-string 2013年多校第4场J题 后缀自动机
- spoj220 每个字符串至少出现两次且不重叠的最长子串(后缀数组)
- 后缀自动机 重复旋律 7 求所有不同的子串的值的总和
- HDU 4622 Reincarnation (区间不相同子串个数:字符串哈希 | 后缀数组 | 后缀自动机)
- HDU3518 后缀数组求不可重叠重复出现的不同子串个数
- hdu 4641 K-string(后缀自动机)
- HDU 4436 str2int(后缀数组,一种统计n个digit字符串所有不同子串之和的方法)
- HDU - 5769 Substring 后缀自动机+二分、新增distinct子串的个数和位置
- hdu 5769后缀数组 求含有某个字母的某个字符串的不同子串的个数
- 后缀自动机(不同子串的个数)hdu4416
- HDU 3518 Boring counting(后缀数组啊 求字符串中不重叠的重复出现至少两次的子串的个数)