L - Ferris Wheel String

Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 43000/43000KB (Java/Others)
Submit Status

Have you ever been to London?

Our Master Qiu will tell you how amazing in London and how funny a Ferris Wheel String is.

One day, while our Master Qiu was recovering Great Britain, he was thinking about an interesting problem about string. In front of him, a London Ferris Wheel was revolving. There were some seats on the large Ferris Wheel. However, in Master Qiu's mind, each seat was a lower-case letter so that the Ferris Wheel was a beautiful string that was revolving all the time. Let's call it Ferris Wheel String.

In the revolving operation, you can put several front letters to the last of the string. Of course, you can also put all the letters to the last, so you will get the string itself. For example, you can change string abcd into 4 strings, such as bcdacdabdabcabcd. Obviously, in the revolving operation, a string of length n can be changed into n strings.

Master Qiu found out an interesting phenomenon that the Ferris Wheel String spent exactly one second revolving one letter. For example, at the beginning(0 second),the Ferris Wheel String was abcd,after one second,it became bcda ... and after four seconds, it became abcd.

Master Qiu is a Romantic guy. He thought after exactly K second(s), the Ferris Wheel String became extremely beautiful.

Now, he would like to ask you a question:

After exactly K second(s), among the n strings obtained by revolving a string of length n, how many distinct strings are lexicographically smaller than the beautiful string, how many distinctstrings are lexicographically equal to the beautiful string and how many distinct strings are lexicographically bigger than the beautiful string ?

(If you really can not understand Master Qiu's mind, see examples and Hint)

Input

The first line contains a string of length n(1≤n≤2⋅105) and the second line contains an integer k(1≤k≤n).

The string only contains lower-case letters.

Output

Output three integers separated by two spaces that are your answer to Master Qiu. Do not output anything after the last integer.

Sample input and output

Sample Input Sample Output
abcabc
1
1 1 1
aaaaaaa
3
0 1 0
himverihimverihimveri
18
0 1 6
lvhqsjtdgckrznjsbargcojiyuf
19
7 1 19
abbabaabbaababbabaababbaabbaba
29
3 1 26

Hint

Let's define that < means lexicographically smaller,> means lexicographically bigger and = means lexicographically equal.
Also, ans1 means the number of strings < bcabca,ans2 means the number of strings = bcabca and ans3 means the number of strings > bacabca.
Explain for lexicography :
Let's only consider lexicographical order between two strings when |S|=|T|.
If S<T, there exits a position p (0≤p<|S|) satisfying that Si=Ti when 0≤i<p but Sp<Tp.
If S>T, there exits a position p (0≤p<|S|) satisfying that Si=Ti when 0≤i<p but Sp>Tp.
If S=T, then Si=Ti for all i (0≤i<|S|)
And we all know that a<b<c< ⋯ <x<y<z.
Explain for the first example :
The Ferris Wheel String is abcabc and K=1 , so that the beautiful string is bcabca
After 1 second, it becomes cabcab, cabcab>bcabca;ans3+=1;
After 2 seconds, it becomes abcabc, abcabc<bcabca;ans1+=1;
After 3 seconds, it becomes bcabca, bcabca=bcabca;ans2+=1;
After 4 seconds, it becomes cabcab. But it has appeared. So, do not count it.
After 5 seconds, it becomes abcabc. But it has appeared. So, do not count it.
After 6 seconds, it becomes bcabca. But it has appeared. So, do not count it.
Therefore, ans1=1, ans2=1 and ans3=1.

Use double hash rather than single hash if you wanna hash.

解题报告:

首先我们将移动后的字符串 * 2处理出来,之后Hash处理,注意使用双哈希.

相同字符换的判断我们将字符串本身的哈希值再哈希即可..

那么字典序如何判断呢?

我们考虑字典序时,前面一段都是一样的,之后在某个位置就不同了,满足二分性质,因此我们通过二分来找到第一个不一样的位置,从而比较字典序的大小

#include <iostream>
#include <cstring>
#include <cstdio>
typedef long long ll;
using namespace std;
const int maxn = 2e5 + , p1 = , mod1 = 1e9 + , p2 = , mod2 = 1e9 + , MaxHashSize = , MaxStatusSize = 2e5 + ;
char str[maxn*],temp[maxn];
int k,len,stdhash1,stdhash2,head[MaxHashSize],next_new[MaxStatusSize],size = ;
ll hash1[maxn*],fac1[maxn+],hash2[maxn*],fac2[maxn+];
typedef struct status
{
int hash1,hash2;
}; status st[MaxStatusSize]; int gethashvalue(int l,int r,int id)
{
ll ans;
if (id == )
{
ans = (hash1[r] - hash1[l-]*fac1[r-l+])%mod1;
if (ans < )
ans += mod1;
return ans;
}
else
{
ans = (hash2[r] - hash2[l-]*fac2[r-l+])%mod2;
if (ans < )
ans += mod2;
return ans;
}
} void init_hash()
{
memset(head,-,sizeof(head));
hash1[] = ,hash2[] = ;
for(int i = ; i <= *len ; ++ i )
hash1[i] = (hash1[i-]*p1 + str[i]) % mod1;
for(int i = ; i <= *len ; ++ i )
hash2[i] = (hash2[i-]*p2 + str[i]) % mod2;
fac1[] = ;
for(int i = ; i <= maxn ; ++ i)
fac1[i] = (fac1[i-]*p1) % mod1;
fac2[] = ;
for(int i = ; i <= maxn ; ++ i)
fac2[i] = (fac2[i-]*p2) % mod2;
} int HashValue(const status &x)
{
return (x.hash1 + x.hash2) % MaxHashSize;
} bool insert(int id)
{
int val = HashValue(st[id]);
int u = head[val];
while(u != -)
{
if (!memcmp(&st[u],&st[id],sizeof(status)))
return false;
u = next_new[u];
}
next_new[id] = head[val];
head[val] = id;
return true;
} void dump(int l,int r)
{
for(int i = l ; i <= r ; ++ i)
printf("%c",str[i]);
printf("\n");
} int main(int argc,char *argv[])
{
scanf("%s%d",str+,&k);len = strlen(str+);
memcpy(temp,str+,k);memcpy(str+,str+k+,len-k);memcpy(str+len-k+,temp,k);memcpy(str+len+,str+,len);init_hash();
stdhash1 = gethashvalue(,len,);
stdhash2 = gethashvalue(,len,);
ll ans1 = , ans2 = , ans3 = ; // < = >
for(int i = ; i <= len+ ; ++ i)
{
st[size].hash1 = gethashvalue(i,i+len-,);
st[size].hash2 = gethashvalue(i,i+len-,);
if (!insert(size))
{
//dump(i,i+len-1);
continue;
}
int thishash1 = st[size].hash1;
int thishash2 = st[size++].hash2;
if (thishash1 == stdhash1 && thishash2 == stdhash2)
{
ans2 ++ ;
continue;
}
if (str[i] != str[])
{
if (str[i] < str[])
ans1++;
else
ans3++;
continue;
}
int l = , r = len-;
while(l < r)
{
int mid = l + (r-l+)/;
int stdh1 = gethashvalue(,mid,);
int stdh2 = gethashvalue(,mid,);
int thish1 = gethashvalue(i,i+mid-,);
int thish2 = gethashvalue(i,i+mid-,);
if (stdh1 == thish1 && stdh2 == thish2)
l = mid;
else
r = mid - ;
}
if (str[i + l] < str[ + l])
ans1++;
else
ans3++;
}
printf("%lld %lld %lld\n",ans1,ans2,ans3);
return ;
}

UESTC_Ferris Wheel String 2015 UESTC Training for Search Algorithm & String<Problem L>的更多相关文章

  1. UESTC_Palindromic String 2015 UESTC Training for Search Algorithm & String<Problem M>

    M - Palindromic String Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 128000/128000KB (Java ...

  2. UESTC_韩爷的梦 2015 UESTC Training for Search Algorithm & String<Problem N>

    N - 韩爷的梦 Time Limit: 200/100MS (Java/Others)     Memory Limit: 1300/1300KB (Java/Others) Submit Stat ...

  3. 2015 UESTC Training for Search Algorithm & String - M - Palindromic String【Manacher回文串】

    O(n)的复杂度求回文串:Manacher算法 定义一个回文值,字符串S是K重回文串,当且仅当S是回文串,且其长度为⌊N/2⌋的前缀和长度为⌊N/2⌋的后缀是K−1重回文串 现在给一个2*10^6长度 ...

  4. 2015 UESTC Training for Search Algorithm & String - J - 全都是秋实大哥 【KMP】

    给出一个字符串,求每个前缀的最小循环节长度,并输出整个字符串的最小循环节.字符串长度为3*10^6 找循环节这种问题还是要用KMP对于长度为i的字符串 i%(i-f[i])==0 此时,它的最小循环节 ...

  5. UESTC_秋实大哥の恋爱物语 2015 UESTC Training for Search Algorithm & String<Problem K>

    K - 秋实大哥の恋爱物语 Time Limit: 5000/2000MS (Java/Others)     Memory Limit: 32000/32000KB (Java/Others) Su ...

  6. UESTC_全都是秋实大哥 2015 UESTC Training for Search Algorithm & String<Problem J>

    J - 全都是秋实大哥 Time Limit: 5000/2000MS (Java/Others)     Memory Limit: 32000/32000KB (Java/Others) Subm ...

  7. UESTC_Infected Land 2015 UESTC Training for Search Algorithm & String<Problem G>

    G - Infected Land Time Limit: 6000/3000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others ...

  8. UESTC_Eight Puzzle 2015 UESTC Training for Search Algorithm & String<Problem F>

    F - Eight Puzzle Time Limit: 3000/1000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) ...

  9. UESTC_吴队长征婚 2015 UESTC Training for Search Algorithm & String<Problem E>

    E - 吴队长征婚 Time Limit: 10000/4000MS (Java/Others)     Memory Limit: 65535/65535KB (Java/Others) Submi ...

随机推荐

  1. 【转载】视频编码(H264概述)

    一视频编码介绍 1.1 视频压缩编码的目标 1)保证压缩比例 2)保证恢复的质量 3)易实现,低成本,可靠性 1.2 压缩的出发点(可行性) 1)时间相关性 在一组视频序列中,相邻相邻两帧只有极少的不 ...

  2. C++模板 静态成员 定义(实例化)

    问一个问题: 考虑一个模板: template <typename T> class Test{ public: static std::string info; }; 对于下面若干种定义 ...

  3. Docker快速搭建neural style环境

    ## 概览 相关的代码都在Github上,请参见我的Github,https://github.com/lijingpeng/neural-style 敬请多多关注哈~~~ ## Docker镜像构建 ...

  4. gcc基本用法

    GCC基本用法 GCC最基本的用法是: gcc [option] filenames option:编译器所需要的编译选项 filenames:要编译的文件名 gcc编译流程 都以 hello.c 为 ...

  5. EffectiveC#7--选择恒定的原子值类型数据

    1.恒定类型就是一但它们被创建,它们(的值)就是固定的. 恒定类型可以很好的在基于哈希代码的集合上工作.以Object.GetHashCode()方法返回的值,对同一个实例是必须相同的 2.一个客户类 ...

  6. HttpWebRequest上传文件(Excel等)

    //上传代码/// <summary> /// 文件上传 /// </summary> /// <param name="strAddress"> ...

  7. MagicalRecord(简化CoreData操作)

    1.新建项目不勾选coredata 2.pod 'MagicalRecord' 3.新建模型文件 4.添加实体和属性 5.Create NSManagedObject subclass 6.增 Per ...

  8. IOS UI篇—UILabel的文字顶部对齐

    UILabel的文字顶部对齐 NOV 20TH, 2011 默认UILabel是垂直居中对齐的,如果你的UILabel高度有多行,当内容少的时候,会自动垂直居中. 如下图所示(图片来自stackove ...

  9. Visual Studio .NET、.NET Framework和C#之间的联系

    Visual Studio .NET是一种集成开发环境(IDE),它包含3种高级程序设计语言,C#就是其中的一种:Visual Studio .NET之所以能把这三种语言有机结合起来并具有与平台无关的 ...

  10. 最强烈推荐-我的java收藏夹(内有国内最好的java论坛)

    原地址: http://bbs.chinaitlab.com/dispbbs.asp?boardid=148&id=34276 国内: www.chinajavaworld.com-论坛人很多 ...