HDU - 4333 Revolving Digits(扩展KMP)
http://acm.hdu.edu.cn/showproblem.php?pid=4333
题意
一个数字,依次将第一位放到最后一位,问小于本身的数的个数及等于本身的个数和大于本身的个数,但是要注意重复的不再计算
分析
当这个串有循环节时才会出现重复串,用KMP的next数组来计算循环节:len-next[len]。最后将得到的答案除以循环节个数即可。然后用扩展KMP,求出主串的后缀与模式串的前缀的最长公共前缀,这里的模式串是原串,而主串则是将两个原串连接起来。利用extend数组,当extend[i]>=n时,说明与原串匹配。否则则比较S[extend[i]]和S[i+extend[i]]的大小(比较不匹配的第一个位置)。
#include<iostream>
#include<cmath>
#include<cstring>
#include<queue>
#include<vector>
#include<cstdio>
#include<algorithm>
#include<map>
#include<set>
#define rep(i,e) for(int i=0;i<(e);i++)
#define rep1(i,e) for(int i=1;i<=(e);i++)
#define repx(i,x,e) for(int i=(x);i<=(e);i++)
#define X first
#define Y second
#define PB push_back
#define MP make_pair
#define mset(var,val) memset(var,val,sizeof(var))
#define scd(a) scanf("%d",&a)
#define scdd(a,b) scanf("%d%d",&a,&b)
#define scddd(a,b,c) scanf("%d%d%d",&a,&b,&c)
#define pd(a) printf("%d\n",a)
#define scl(a) scanf("%lld",&a)
#define scll(a,b) scanf("%lld%lld",&a,&b)
#define sclll(a,b,c) scanf("%lld%lld%lld",&a,&b,&c)
#define IOS ios::sync_with_stdio(false);cin.tie(0)
#define lc idx<<1
#define rc idx<<1|1
#define lson l,mid,lc
#define rson mid+1,r,rc
using namespace std;
typedef long long ll;
template <class T>
void test(T a){cout<<a<<endl;}
template <class T,class T2>
void test(T a,T2 b){cout<<a<<" "<<b<<endl;}
template <class T,class T2,class T3>
void test(T a,T2 b,T3 c){cout<<a<<" "<<b<<" "<<c<<endl;}
const int N = 1e6+;
const int inf = 0x3f3f3f3f;
const ll INF = 0x3f3f3f3f3f3f3f3fll;
const ll mod = ;
int T;
void testcase(){
printf("Case %d:",++T);
}
const int MAXN = 2e5+;
const int MAXM = ;
const int p = ; int nxt[MAXN],extend[MAXN];
char s[MAXN],t[MAXN>>]; void get_next(int m){
int i,j;
j=nxt[]=-;
i=;
while(i<m){
while(-!=j&&t[i]!=t[j]) j=nxt[j];
if(t[++i]==t[++j]) nxt[i]=nxt[j];
else nxt[i]=j;
}
} void pre_EKMP(int m){
nxt[]=m;
int j=;
while(j+<m&&t[j]==t[j+]) j++;
nxt[]=j;
int k=;
for(int i=;i<m;i++){
int p =nxt[k]+k-;
int L=nxt[i-k];
if(i+L<p+) nxt[i]=L;
else{
j=max(,p-i+);
while(i+j<m&&t[i+j]==t[j]) j++;
nxt[i]=j;
k=i;
}
}
} void EKMP(int m,int n){
pre_EKMP(m);
int j=;
while(j<n&&j<m&&t[j]==s[j]) j++;
extend[]=j;
int k=;
for(int i=;i<n;i++){
int p =extend[k]+k-;
int L=nxt[i-k];
if(i+L<p+) extend[i]=L;
else{
j=max(,p-i+);
while(i+j<n&&j<m&&s[i+j]==t[j]) j++;
extend[i]=j;
k=i;
}
}
} void solve(){
int lt=strlen(t);
int ls=strlen(s);
get_next(lt);
int k=lt-nxt[lt];
k= lt%k==?(lt/k):;
EKMP(lt,ls);
int e=,g=,l=;
for(int i=;i<lt;i++){
if(extend[i]>=lt) e++;
else if(s[extend[i]]>s[i+extend[i]]) l++;
else g++;
}
printf(" %d %d %d\n",l/k,e/k,g/k);
}
int main() {
#ifdef LOCAL
freopen("in.txt","r",stdin);
#endif // LOCAL
int tt;
T=;
scd(tt);
while(tt--){
scanf("%s",s);
strcpy(t,s);
strcat(s,t);
testcase();
solve();
}
return ;
}
HDU - 4333 Revolving Digits(扩展KMP)的更多相关文章
- HDU 4333 Revolving Digits 扩展KMP
链接:http://acm.hdu.edu.cn/showproblem.php?pid=4333 题意:给以数字字符串,移动最后若干位到最前边,统计得到的数字有多少比原来大,有多少和原来同样,有多少 ...
- HDU 4333 Revolving Digits [扩展KMP]【学习笔记】
题意:给一个数字,每一次把它的最后一位拿到最前面,一直那样下去,分别求形成的数字小于,等于和大于原来数的个数. SAM乱搞失败 当然要先变SS了 然后考虑每个后缀前长为n个字符,把它跟S比较就行了 如 ...
- 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) ...
- 扩展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 ...
随机推荐
- ModSecurity is an open source, cross-platform web application firewall (WAF) module.
http://www.modsecurity.org/ ModSecurity is an open source, cross-platform web application firewall ( ...
- Linux 下载安装配置Redis完整步骤
安装: 1.获取redis资源 wget http://download.redis.io/releases/redis-4.0.8.tar.gz 2.解压 tar xzvf redis-4.0.8. ...
- Uva821-Floyd
计算所有页面的平均距离. 用floyd求距离,再求平均 #include <algorithm> #include <cstring> #include <ctype.h ...
- CUBA如何新增ServiceBean
简单的方法 在页面MIDDLEWARE模块,可以直接新建.编辑.删除 复杂的方法 在代码中手动实现,则需要1.添加Serviceweb-spring.xml中,添加 <entry key=&qu ...
- Git储藏与恢复
cd /f cd android git status echo 'shoping' >> 4 //修改内容 git status git stash //git储藏 git status ...
- Python解惑:整数比较
在 Python 中一切都是对象,毫无例外整数也是对象,对象之间比较是否相等可以用==,也可以用is.==和is操作的区别是: is比较的是两个对象的id值是否相等,也就是比较俩对象是否为同一个实例对 ...
- 学习Spring Boot:(二十六)使用 RabbitMQ 消息队列
前言 前面学习了 RabbitMQ 基础,现在主要记录下学习 Spring Boot 整合 RabbitMQ ,调用它的 API ,以及中间使用的相关功能的记录. 相关的可以去我的博客/RabbitM ...
- 并发容器——ConcurrentHashMap
ConcurreentHashMap的实现原理与使用 ConcurrentHashMap是线程安全且高效的HashMap. 为什么要使用ConcurrentHashMap 在并发编程中使用HashMa ...
- NHibernate使用简单示例
NHibernate使用小示例 1.新建Model类库项目. 使用代码生成器生成Model类. 此处以简单的UserInfo表作为示例. 注意字段前必须以 virtual 修饰. namespace ...
- javascript高级程序设计第二章知识点提炼
这是我整理的javascript高级程序设计第二章的脑图,内容也是非常浅显与简单.希望您看了我的博客能够给我一些意见或者建议.