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)的更多相关文章

  1. HDU 4333 Revolving Digits 扩展KMP

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

  2. HDU 4333 Revolving Digits [扩展KMP]【学习笔记】

    题意:给一个数字,每一次把它的最后一位拿到最前面,一直那样下去,分别求形成的数字小于,等于和大于原来数的个数. SAM乱搞失败 当然要先变SS了 然后考虑每个后缀前长为n个字符,把它跟S比较就行了 如 ...

  3. HDU 4333 Revolving Digits 扩张KMP

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

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

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

  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. PHP文件下载功能实现

    客户端的浏览器通过HTTP协议可以实现文件下载: 方法一: 能提供用户下载的最简单的方法就是使用一个<a></a>标签,比如在页面中添加这么一行代码 <a href=&q ...

  2. Eclipse频繁崩溃问题待解决

    ---------------------------Eclipse---------------------------Java was started but returned exit code ...

  3. 一种快速统计SQL Server每个表行数的方法

    转载自:http://www.cnblogs.com/kenyang/archive/2013/04/09/3011447.html 我们都知道用聚合函数count()可以统计表的行数.如果需要统计数 ...

  4. XMLHttpRequest详解

    XMLHttpRequest详解: https://xhr.spec.whatwg.org/

  5. [书摘]图解HTTP 状态码

    状态码类别: 1XX informational 信息性状态码 2XX Suess   成功状态码 3XX Redirection 重定向状态码 4XX Client error 客户端错误状态码 5 ...

  6. python中字典和json的区别

    python中,json和dict非常类似,都是key-value的形式,而且json.dict也可以非常方便的通过dumps.loads互转 定义 python中,json和dict非常类似,都是k ...

  7. jenkins--java配置

    进入jenkins然后-->系统配置-->Global Tool Configuration

  8. ceph 安装过程

    安装依赖: yum install -y yum-utils && yum-config-manager --add-repo https://dl.fedoraproject.org ...

  9. BZOJ4517[Scoi2016]美味——主席树

    题目描述 一家餐厅有 n 道菜,编号 1...n ,大家对第 i 道菜的评价值为 ai(1≤i≤n).有 m 位顾客,第 i 位顾客的期 望值为 bi,而他的偏好值为 xi .因此,第 i 位顾客认为 ...

  10. Vue模板 script部分

    <script> export default { name: "Home", data() { return {}; }, methods: { // 组件的方法 } ...