HDU 4333 Revolving Digits [扩展KMP]【学习笔记】
题意:给一个数字,每一次把它的最后一位拿到最前面,一直那样下去,分别求形成的数字小于,等于和大于原来数的个数。
SAM乱搞失败
当然要先变SS了
然后考虑每个后缀前长为n个字符,把它跟S比较就行了
如果用后缀家族的话复杂度要加上log,本题会TLE吧
求一个串S的每个后缀与另一个串T的最长公共前缀可以用扩展KMP!复杂度O(n+m)
看课件吧
从1开始写真不容易以后再也不从1开始了,判断位置好麻烦好容易错
next[i]=LCP(T[i,m],T)
extend[i]=LCP(S[i,n],T)
主要思想就是求i时记录p=max{a+extend[a]-1},1<=a<i 也就是当前最远匹配到哪里,这么做是为了以后直接利用next的信息
S[a,a+extend[a]-1]--->T[1,extend[a]-1]是一样的
那么从i开始的后缀的前一部分是和T[i-a+1..]相同的,就不用比较了因为已经有L=next[i-a+1]了
如果i+L-1<p,extend[i]=L
否则从s[p+1]和t[p-i+1+1]开始暴力往后匹配,并更新a
注意:本题要求不相同的数字,出现相同数字说明有循环节,KMP求一下看看有没有可以整除的循环节
#include <cstdio>
#include <cstring>
using namespace std;
const int N=2e6+;
inline int read(){
char c=getchar();int x=,f=;
while(c<''||c>''){if(c=='-')f=-; c=getchar();}
while(c>=''&&c<=''){x=x*+c-''; c=getchar();}
return x*f;
}
inline int min(int a,int b){return a<b?a:b;}
inline int max(int a,int b){return a>b?a:b;}
int n,m;
int next[N],extend[N];
char s[N],t[N];
void getNext(char s[],int n){
//printf("getNext %d\n",n);
//for(int i=1;i<=n;i++) printf("%c",s[i]); next[]=n;
int a=;
while(a<n&&s[a]==s[a+]) a++;
next[]=a-;
a=;
for(int i=;i<=n;i++){
int p=a+next[a]-,L=next[i-a+];
if(i+L-<p) next[i]=L;
else{
int j=max(p-i+,);//!!
while(i+j<=n&&s[i+j]==s[j+]) j++;
next[i]=j;a=i;
}
}
//for(int i=1;i<=n;i++) printf("next %d %d\n",i,next[i]);
}
void getExtend(char s[],char t[]){
//printf("getExtend %d\n",n);
//for(int i=1;i<=n;i++) printf("%c",s[i]);puts("");
getNext(t,m);
int mn=min(n,m),a=;
while(a<=mn&&s[a]==t[a]) a++;
extend[]=a-;
a=;
for(int i=;i<=n;i++){
int p=a+extend[a]-,L=next[i-a+];
if(i+L-<p) extend[i]=L;
else{
int j=max(p-i+,);
while(i+j<=n&&s[i+j]==t[j+]) j++;
extend[i]=j;
a=i;
}
}
//for(int i=1;i<=n;i++) printf("extend %d %d\n",i,extend[i]);
}
int fail[N];
void getFail(char s[],int n){
fail[]=;
for(int i=;i<=n;i++){
int j=fail[i-];
while(j&&s[j+]!=s[i]) j=fail[j];
fail[i]=s[j+]==s[i]?j+:;
}
}
int L,E,G;
void solve(){
getExtend(s,t);
L=E=G=;
for(int i=;i<=m;i++){
int lcp=extend[i];
if(lcp>=m) E++;
else if(t[+lcp]<s[i+lcp]) G++;
else L++;
}
//for(int i=1;i<=n;i++) printf("hi %d %d %d\n",i,next[i],extend[i]);
getFail(t,m);
int _=m%(m-fail[m])==?m/(m-fail[m]):;
L/=_;E/=_;G/=_;
} int main(){
freopen("in","r",stdin);
int T=read(),cas=;
while(T--){
scanf("%s",s+);
n=m=strlen(s+);
for(int i=;i<=n;i++) s[i+n]=t[i]=s[i];
n<<=;
solve();
printf("Case %d: %d %d %d\n",++cas,L,E,G);
}
}
HDU 4333 Revolving Digits [扩展KMP]【学习笔记】的更多相关文章
- HDU 4333 Revolving Digits 扩展KMP
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4333 题意:给以数字字符串,移动最后若干位到最前边,统计得到的数字有多少比原来大,有多少和原来同样,有多少 ...
- HDU 4333 Revolving Digits 扩张KMP
标题来源:HDU 4333 Revolving Digits 意甲冠军:求一个数字环路移动少于不同数量 等同 于的数字 思路:扩展KMP求出S[i..j]等于S[0..j-i]的最长前缀 推断 nex ...
- 字符串(扩展KMP):HDU 4333 Revolving Digits
Revolving Digits Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- HDU - 4333 Revolving Digits(扩展KMP)
http://acm.hdu.edu.cn/showproblem.php?pid=4333 题意 一个数字,依次将第一位放到最后一位,问小于本身的数的个数及等于本身的个数和大于本身的个数,但是要注意 ...
- 扩展KMP - HDU 4333 Revolving Digits
Revolving Digits Problem's Link Mean: 给你一个字符串,你可以将该字符串的任意长度后缀截取下来然后接到最前面,让你统计所有新串中有多少种字典序小于.等于.大于原串. ...
- 【扩展kmp+最小循环节】HDU 4333 Revolving Digits
http://acm.hdu.edu.cn/showproblem.php?pid=4333 [题意] 给定一个数字<=10^100000,每次将该数的第一位放到放到最后一位,求所有组成的不同的 ...
- HDU - 4333 Revolving Digits(拓展kmp+最小循环节)
1.给一个数字字符串s,可以把它的最后一个字符放到最前面变为另一个数字,直到又变为原来的s.求这个过程中比原来的数字小的.相等的.大的数字各有多少. 例如:字符串123,变换过程:123 -> ...
- hdu4333 Revolving Digits(扩展kmp)
Revolving Digits Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) ...
- Hdu 4333 Revolving Digits(Exkmp)
Revolving Digits Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...
随机推荐
- JAVA实现网页上传头像
大概实现就是在页面嵌入一个file类型的input控件,并且将之隐藏,点击上传传递到这个控件上面,选择文件,将图片以base64的方式传递到后台,后台解码器解码,保存图片,并且把图片名字保存到数据库或 ...
- Spark环境搭建(下)——Spark安装
1. 下载Spark 1.1 官网下载Spark http://spark.apache.org/downloads.html 打开上述链接,进入到下图,点击红框下载Spark-2.2.0-bin-h ...
- 转:深入理解Java的接口和抽象类
转载原文链接: http://www.cnblogs.com/dolphin0520/p/3811437.html 一.抽象类 在了解抽象类之前,先来了解一下抽象方法.抽象方法是一种特殊的方法:它只有 ...
- 在Ubuntu虚拟机搭建数据库系统
连接数据库: mysql -uroot -p 输入数据库密码即可登陆. 查看mysql版本信息: mysql> select version(); +---------------------- ...
- Spring MVC 学习总结(一)——MVC概要与环境配置 转载自【张果】博客
Spring MVC 学习总结(一)--MVC概要与环境配置 目录 一.MVC概要 二.Spring MVC介绍 三.第一个Spring MVC 项目:Hello World 3.1.通过Mave ...
- iptabes的用法
iptables的用法 基本用法: iptables [-t table] [subcommand] chain [rulenum] [options...] [match] [target] ipt ...
- 第一章 用HTML5中的结构元素构建网站
1.当一个容器需要直接定义样式或通过脚本定义行为时,推荐使用div元素而非section元素. 2.section是需要标题的,而nav或aside没有标题也是可以的. 3.html5轮廓工具 htt ...
- 数据库连接池(c3p0)
(一)问题的提出: 在使用开发基于数据库的web程序时,传统的数据库使用模式按照以下步骤: 在程序中建立数据库连接 进行sql操作 断开数据库连接 但是,这种模式存在着移动的问题: 传统连接模式每次向 ...
- -------- Rootkit 核心技术——利用 nt!_MDL 突破 KiServiceTable 的只读访问限制 Part II --------
------------------------------------------------------------------------------------------- 本篇开始进入正题 ...
- python3 第十五章 - 数据类型之Sets(集合)
python的官网里对集合的描述是: Python also includes a data type for sets. A set is an unordered collection with ...