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 ...
随机推荐
- android组件化方案、二维码扫码、Kotlin新闻客户端、动画特效等源码
Android精选源码 CalendarView日历选择器 android下拉刷新动画效果代码 一个非常方便的fragment页面框架 android组件化方案源码 Zxing实现二维码条形码的扫描和 ...
- 再起航,我的学习笔记之JavaScript设计模式29(节流模式)
节流模式 概念介绍 节流模式(Throttler): 对重复的业务逻辑进行节流控制,执行最后一次操作并取消其他操作,以提高性能. 优化滚动事件 有的时候我们再为滚动条添加动画的时候,会发现滚动条不停的 ...
- Vue2反向代理
前一段时间写了一个vue2的小项目,用的是vue-cli脚手架搭建的项目,项目里需要跨域,但又不能使用jsonp,上网查了一下,发现有一个之前没接触过的词语--反向代理. 什么是"反向代 ...
- linux 树型显示文件 tree ls tree 命令
原创 2016年07月27日 09:50:19 yum install tree tree www │?? │?? │?? └── xml.test │?? │?? └── valgrind.su ...
- SSL协议之数据加密过程详解
前言 总括: 原文博客地址:SSL协议之数据加密过程详解 知乎专栏&&简书专题:前端进击者(知乎)&&前端进击者(简书) 博主博客地址:Damonare的个人博客 生活 ...
- 基于TI CC2650的IPv6 over BLE(BLEach) demo
虽然BLE 5.0协议理论上已经开始支持IPv6了,但是目前市面上还没有可用的实现IPv6通信的BLE产品. 最近在网上看到一个开源的基于contiki系统,在CC2650上实现的IPv6 over ...
- 新版Azure Automation Account 浅析(二) --- 更新Powershell模块和创建Runbook
前篇我们讲了怎样创建一个自动化账户以及创建时候"Run As Account"选项背后的奥秘.这一篇针对在Azure自动化账户中使用Powershell Runbook的用户讲一下 ...
- Java泛型范例
class Point<T>{ // 此处可以随便写标识符号,T是type的简称 private T var ; // var的类型由T指定,即:由外部指定 public T getVar ...
- 通读cheerio API ——NodeJs中的jquery
通读cheerio API ——NodeJs中的jquery 所谓工欲善其事,必先利其器,所以通读了cheerio的API,顺便翻译了一遍,有些地方因为知道的比较少,不知道什么意思,保留了英文,希望各 ...
- Java数据持久层框架 MyBatis之API学习三(XML 映射配置文件)
对于MyBatis的学习而言,最好去MyBatis的官方文档:http://www.mybatis.org/mybatis-3/zh/index.html 对于语言的学习而言,马上上手去编程,多多练习 ...