题意:给一个数字,每一次把它的最后一位拿到最前面,一直那样下去,分别求形成的数字小于,等于和大于原来数的个数。


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]【学习笔记】的更多相关文章

  1. HDU 4333 Revolving Digits 扩展KMP

    链接:http://acm.hdu.edu.cn/showproblem.php?pid=4333 题意:给以数字字符串,移动最后若干位到最前边,统计得到的数字有多少比原来大,有多少和原来同样,有多少 ...

  2. HDU 4333 Revolving Digits 扩张KMP

    标题来源:HDU 4333 Revolving Digits 意甲冠军:求一个数字环路移动少于不同数量 等同 于的数字 思路:扩展KMP求出S[i..j]等于S[0..j-i]的最长前缀 推断 nex ...

  3. 字符串(扩展KMP):HDU 4333 Revolving Digits

    Revolving Digits Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  4. HDU - 4333 Revolving Digits(扩展KMP)

    http://acm.hdu.edu.cn/showproblem.php?pid=4333 题意 一个数字,依次将第一位放到最后一位,问小于本身的数的个数及等于本身的个数和大于本身的个数,但是要注意 ...

  5. 扩展KMP - HDU 4333 Revolving Digits

    Revolving Digits Problem's Link Mean: 给你一个字符串,你可以将该字符串的任意长度后缀截取下来然后接到最前面,让你统计所有新串中有多少种字典序小于.等于.大于原串. ...

  6. 【扩展kmp+最小循环节】HDU 4333 Revolving Digits

    http://acm.hdu.edu.cn/showproblem.php?pid=4333 [题意] 给定一个数字<=10^100000,每次将该数的第一位放到放到最后一位,求所有组成的不同的 ...

  7. HDU - 4333 Revolving Digits(拓展kmp+最小循环节)

    1.给一个数字字符串s,可以把它的最后一个字符放到最前面变为另一个数字,直到又变为原来的s.求这个过程中比原来的数字小的.相等的.大的数字各有多少. 例如:字符串123,变换过程:123 -> ...

  8. hdu4333 Revolving Digits(扩展kmp)

    Revolving Digits Time Limit: 3000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) ...

  9. Hdu 4333 Revolving Digits(Exkmp)

    Revolving Digits Time Limit: 3000/1000 MS (Java/Others) Memory Limit: 65536/32768 K (Java/Others) To ...

随机推荐

  1. c语言几个松散的地方(不足的地方,不严谨的地方,它容易出错的地方)。

    c语言是面向过程的语言,是弱类型语言,c语言的源代码基本就是无数个函数的堆砌.即很多函数就组成c语言源代码了,也即它的源代码基本就是函数构成的. C语言里面的test()和test(void)是不一样 ...

  2. Linux下采用VI编辑器删除复制或移动多行文本内容

    一.删除多行 单行删除,:1(待删除行号)d 多行删除,:1,10d dd 删除光标所在行ndd删除以当前行开始的n行dw删除以当前字符开始的一个字符ndw删除以当前字符开始的n个字符d$.D删除以当 ...

  3. Dora.Interception, 一个为.NET Core度身打造的AOP框架[3]:Interceptor的注册

    在<不一样的Interceptor>中我们着重介绍了Dora.Interception中最为核心的对象Interceptor,以及定义Interceptor类型的一些约定.由于Interc ...

  4. 从零开始学习前端开发 — 11、CSS3选择器

    一.基本选择器 1.* 通配符(通用选择器) 2.id选择器 3.class选择器(类选择器) 4.标签选择器(元素选择符) 5.群组选择器 (选择符1,选择符2{...}) 二.层次选择器(关系选择 ...

  5. 怎么从一台电脑的浏览器输入地址访问另一台电脑服务器(WAMP服务器已搭建,PHPSTORM装好了)

    服务器电脑WAMP环境搭建好了,浏览器输入LOCALHOST就能访问本地 WAMP/WWW 目录下PHP文件,怎么样才能从另一台电脑通过浏览器访问呢?求详细步骤... glwbdtb | 浏览 180 ...

  6. dede添加会员功能听语音

    http://jingyan.baidu.com/article/363872ec36d33f6e4ba16fb7.html 其实 dede里面的 会员功能就是圈子模版啦 圈子 安装了 基本上有 1, ...

  7. 2.移植3.4内核-使内核支持烧写yaffs2

    在上章-制作文件系统,并使内核成功启动jffs2文件系统了 本章便开始使内核支持烧写yaffs2文件系统 1.首先获取yaffs2源码(参考git命令使用详解) cd /work/nfs_root g ...

  8. @synchronized(self)

    @synchronized 的作用是创建一个互斥锁,保证此时没有其它线程对self对象进行修改.这个是objective-c的一个锁定令牌,防止self对象在同一时间内被其 它线程访问,起到线程的保护 ...

  9. bootstrap简单图文环绕效果

    一.      下载bootstrap-3.3.7 二.      在html页面引入css,js; eg: <link src="bootstrap-3.3.7-dist/css/b ...

  10. 用photoshop将图片四角变成圆角

    1.用PS打开一张图片,用矩形选框工具,选出你要保留的的那一部分,"选择→修改→平滑".在弹出的选框里添入数值,值越大角就越圆. 2.然后选择"选择→反选"再按 ...