扩展KMP+KMP+hdu4333
来源:互联网 发布:电信 网络重构 编辑:程序博客网 时间:2024/05/01 03:08
自己就是想不到,智商是硬伤啊
思路:扩展KMP能求出一个串所有后缀串(即s[i...len])和模式串的最长公共前缀。于是只要将这个串复制一遍,拼接到后面,求出拼接后的串每个后缀与原来串的最长公共前缀即可,当公共前缀>=len时,显然相等,否则只要比较下一位就能确定这个串与原串的大小关系。至于重复串的问题,只有当这个串有循环节的时候才会产生重复串,用KMP的next数组求出最小循环节,用长度除以最小循环节得到循环节个数,在将3个答案都除以循环节个数即可。
#include<iostream>#include<cstdio>#include<cstring>#include<vector>#include<cmath>#include<string>#include<queue>#include<stack>#include<map>#include<set>#include<algorithm>using namespace std;const int maxn=200010;int next[maxn/2],extend[maxn];char s[maxn],s1[maxn/2];int n;void getnext(char *ss){ n=strlen(ss); next[0]=n; int j=0; while(j+1<n&&ss[j+1]==ss[j])j++; next[1]=j; int k=1; for(int i=2;i<n;i++) { int p=next[k]+k-1; int l=next[i-k]; if(i+l<p+1)next[i]=l; else { int j=max(0,p-i+1); while(i+j<n&&ss[i+j]==ss[j])j++; next[i]=j; k=i; } }}void getextend(char * S,char * T){ memset(next,0,sizeof(next)); getnext(T); int j=0; int slen=strlen(S),tlen=strlen(T); int minlen=min(slen,tlen); while(j<minlen&&S[j]==T[j])j++; extend[0]=j; int k=0; for(int i=1;i<slen;i++) { int p=extend[k]+k-1; int l=next[i-k]; if(i+l<p+1)extend[i]=l; else { int j=max(0,p-i+1); while(i+j<slen&&j<tlen&&S[i+j]==T[j])j++; extend[i]=j; k=i; } }}void getf(char * ss){ int i=0,j=-1; int len=strlen(ss); next[0]=-1; while(i<len) { if(j==-1||ss[i]==ss[j]) { i++,j++; next[i]=j; } else j=next[j]; }}void solve(){ int L=0,E=0,G=0; for(int i=0;i<n;i++) { if(extend[i]>=n)E++; else if(s[(extend[i])%n]>=s[(i+extend[i])%n])L++; else G++; } int cir=1; int len=strlen(s1); if(len%(len-next[len])==0)cir=len/(len-next[len]); printf("%d %d %d\n",L/cir,E/cir,G/cir);}int main(){ int T,cas=1; scanf("%d",&T); while(T--) { scanf("%s",s); strcpy(s1,s); strcat(s,s1); getextend(s,s1); getf(s1); printf("Case %d: ",cas++); solve(); } return 0;}
0 0
- 扩展KMP+KMP+hdu4333
- hdu4333之扩展KMP
- 【hdu4333】扩展kmp算法
- hdu4333 扩展kmp
- 扩展kmp(HDU4333)
- hdu4333 Revolving Digits(扩展kmp)
- HDU4333 Revolving Digits(KMP+扩展KMP)
- hdu4333 Revolving Digits(扩展kmp+kmp最小循环节)
- hdu4333——拓展kmp
- hdu4333-拓展kmp-Revolving Digits
- HDU4333:Revolving Digits(拓展kmp)
- hdu4333 Revolving Digits(kmp+exkmp)
- KMP和扩展KMP
- KMP和扩展KMP
- kmp与kmp扩展
- KMP和扩展KMP
- KMP与扩展KMP
- KMP和扩展KMP
- java中堆和栈的区别
- 如何在windows server2012中查看已安装的证书
- 医院污物真空管道收集系统综述报告
- 流程虚拟机——jBPM产品思想分析.pdf
- 修改Eclipse/MyEclipse项目的默认编码
- 扩展KMP+KMP+hdu4333
- STL——vector
- Training--使用Fragment创建动态UI
- 内核工具 – Sparse 简介,:__attribute, __context__
- jQuery 学习(三)
- Given an array of integers, every element appears twice except for one. Find that single one.
- bzoj1196: [HNOI2006]公路修建问题 二分答案
- Eureka 的 Application Client 客户端的运行示例
- 什么是艺术--草论