hdu3336 &&hdu 4552 KMP ,SAM
来源:互联网 发布:淘宝中年女模特叫什么 编辑:程序博客网 时间:2024/06/04 19:27
给一个串,求所有前缀在母串中出现的次数和。
还是利用失配函数来做,构造完失配函数,然后从末尾向前枚举,对于每个点,如果没有被访问过的话,就沿其失配路径走一遍,并且每经过一个未访问过节点,迭代层数+1(初始为0),若经过的是已经访问的节点,那么迭代层数不变;同时标记该点已访问,这个点为末尾的前缀出现的次数+当前迭代的层数,然后转移到向下一个点;对KMP的失配函数深入了解一点的话,这个思路也挺好理解的,举个例子,aba....aba....aba 第一次迭代,末尾-->3 3标记掉,层数+1=1,3-->1,标记掉层数+1=2,此时a出现了两次;枚举到中间那个aba的时候,'a'-->3,层数+1=1,发现3访问过了,所以3-->1的时候层数不变还是1,然后a出现的次数+1,如果层数每次都是+1的话,显然第二次3-->1的时候,3位置的a被重复统计了,所以在从被访问过的点转移的时候,迭代的层数是保持不变的。
#include <iostream>#include <cstring>#include <algorithm>#include <cstdio>#include <cmath>using namespace std;typedef long long ll;const int maxn=210000;bool ok[maxn];int f[maxn];char s[maxn],ss[maxn];int cnt[maxn];void getFail(char* P,int* f){ int m=strlen(P); f[0]=0; f[1]=0; for (int i=1; i<m; i++) { int j=f[i]; while(j && P[i]!=P[j]) j=f[j]; f[i+1]=P[i]==P[j]?j+1:0; }}bool find(char* T,char* P,int* f){ int n=strlen(T); int m=strlen(P);// getFail(P,f); int j=0; for (int i=0; i<n; i++) { while(j && P[j]!=T[i]) j=f[j]; if (P[j]==T[i]) j++; if (j==m) return true; } return false;}int tt;int n,m,k;void slove(int pos,int x){ if (!pos) return; cnt[pos]+=x; if (!ok[pos]) slove(f[pos],x+1); else slove(f[pos],x); ok[pos]=true;}int main(){// freopen("in.txt","r",stdin); scanf("%d",&tt); while(tt--) { scanf("%d",&n); scanf("%s",s);// for (int i=0; i<n; i++)// s[i]=ss[n-i-1];// s[n]='\0'; getFail(s,f); memset(ok,0,sizeof ok); memset(cnt,0,sizeof cnt); for (int i=n; i>=0; i--) { if (ok[i]) continue; int p=i; if (p && !ok[p]) { slove(p,0);// cnt[f[p]]+=1; } } ll ans=0; for (int i=1; i<=n; i++) ans+=cnt[i]+1,ans%=10007; cout<<ans<<endl;// cout<<cnt[i]+1<<" ";// cout<<endl; } return 0;}
4552 这题好像和3336一模一样,这种子串+统计的问题几乎全能用后缀自动机(SAM)做,当时学SAM的时候顺道把这题做了,写SAM的话几乎就是个裸题了..统计一下节点出现次数,累加取模就是答案...
#include <iostream>#include <cstdio>#include <memory.h>#include <algorithm>#include <cmath>#include <string>#include <cstring>using namespace std;const int maxn=210000;const int S=26;const int inf=maxn;char str[maxn>>1],s[maxn>>1],st[maxn>>1];int c[maxn];struct node{ node *par,*go[S]; int val,sp;}*root,*tail,que[maxn],*top[maxn];int tot,len;int ans;int wtop[maxn];int l;inline int idx(char c){ return (int)c-'a';}inline void add(int c,int l){ node *p=tail; node *np=&que[tot++]; np->val=l; //np->n1=0; while (p&&p->go[c]==NULL) p->go[c]=np,p=p->par; if (p==NULL) np->par=root; else { node *q=p->go[c]; if (p->val+1==q->val) np->par=q; else { node *nq=&que[tot++]; *nq=*q; nq->val=p->val+1; np->par=q->par=nq; while (p&&p->go[c]==q) p->go[c]=nq,p=p->par; } } tail=np;}inline void init(){ memset(que,0,sizeof que); len=1; tot=0; memset(wtop,0,sizeof wtop); ans=0; root=tail=&que[tot++];}inline void TopS(){ memset(c,0,sizeof c); for (int i=0; i<tot; i++) c[que[i].val]++; for (int i=1; i<=len; i++) c[i]+=c[i-1]; for (int i=0; i<tot; i++) { top[--c[que[i].val]]=&que[i]; wtop[c[que[i].val]]=i; }}int main(){ //freopen("a.txt","r",stdin); while (~scanf("%s",str)) { l=strlen(str); init(); for (int i=0; i<l; i++) { add(idx(str[i]),len++); } TopS(); node *p=root; for (int i=0; i<l; i++) { p=p->go[idx(str[i])]; p->sp=1; } for (int i=tot-1; i>0; i--) { p=top[i]; p->par->sp+=p->sp; p->par->sp%=256; } p=root; int ans=0; for (int i=0; i<l; i++) { p=p->go[idx(str[i])]; ans+=p->sp; ans=ans%256; } printf("%d\n",ans); } return 0;}
0 0
- hdu3336 &&hdu 4552 KMP ,SAM
- KMP题 hdu3336 hdu3746 hdu 1358 hdu2594
- hdu3336(KMP)
- HDU3336-KMP
- hdu3336 KMP
- hdu3336(kmp)
- HDU3336(KMP)
- hdu3336 KMP
- HDU3336------KMP+DP
- hdu3336之KMP应用
- hdu3336(KMP+DP)
- hdu3336(KMP+DP)
- hdu3336(kmp+dp)
- hdu3336 KMP应用
- 【KMP】 hdu3336 Count the string
- hdu3336 Count the string-------KMP
- hdu3336 Count the string KMP
- [KMP][HDU3336][Count the string]
- mdb数据库文件如何导入到Microsoft SQL Server 2008中
- catalan数,两排,分别从低到高排序,第二排相应的比第一排高
- UFLDL教程—自编码线性解码器学习
- 复古式的立体CSS菜单实例
- Ten的XHR
- hdu3336 &&hdu 4552 KMP ,SAM
- 有一个整数数组,请求出两两之差绝对值最小的值,记住,只要得出最小值即可,不需要求出是哪两个数。
- Aspect
- 动态规划
- Medoo Select的使用:查询数据
- Hadoop源代码分析之Hadoop RPC(RPC和Client)
- 装饰模式
- AJAX file uploads in Rails using attachment_fu and responds_to_parent 1
- windows 组播网卡绑定,解决多网卡通信异常问题。