题目描述

给出一个由小写英文字母组成的字符串S,再给出q个询问,要求回答S某个子串的最短循环节。
如果字符串B是字符串A的循环节,那么A可以由B重复若干次得到。

输入

第一行一个正整数n (n<=500,000),表示S的长度。
第二行n个小写英文字母,表示字符串S。
第三行一个正整数q (q<=2,000,000),表示询问个数。
下面q行每行两个正整数a,b (1<=a<=b<=n),表示询问字符串S[a..b]的最短循环节长度。

输出

依次输出q行正整数,第i行的正整数对应第i个询问的答案。

样例输入

8
aaabcabc
3
1 3
3 8
4 8

样例输出

1
3
5
 
 对于一个串的循环节有几个性质,这些性质也是解题的关键所在:
1、如果B串是A串的循环节,那么B串长度一定是A串长度的约数。
2、如果B串是A串的循环节,设A串区间为[l,r],B串长度为x,[l+x,r]和[l,r-x]一定相同(判断循环节的关键所在),这个很好证明,因为A串由几个B拼接而成,从前面拿掉一个B和从后面拿掉一个B,剩下串自然是一样的。
3、如果B串是A串的最短循环节,那么所有A串循环节的长度都是B串长度的倍数,也就是说不是B串长度倍数的一定不是循环节。举个例子:假如A串长度为6(每个字符分别用s1,s2,s3,s4,s5,s6表示),最短循环节长度为2,长度为3的子串一定不是循环节,因为s1=s3=s5,s2=s4=s6且s1≠s2即s1≠s4,但如果长度为3的是循环节,s1=s4,显然矛盾,由此推广就能证明上述结论。
因为一个A串的长度由几个质因子相乘得到,所以只要判断长度除掉某个质因子之后得到的子串是否为循环节,如果是,就说明这个串中是最短循环节的倍数。这里用线性筛法筛质因子,在线性筛素数时记录每个数的最小质因子,每个查询是枚举质因子O(1)判断。
这三道题中有一道卡自然溢出。
最后附上代码。
#include<cstdio>
#include<algorithm>
#include<iostream>
#include<cstring>
#include<cmath>
#include<queue>
#include<map>
using namespace std;
unsigned long long h[500010];
long long g[500010];
long long m[500010];
unsigned long long k[500010];
const int base=13131;
long long mod=2333333333ll;
int vis[500010];
int prime[100010];
int s[500010];
char ch[500010];
int n,q;
int l,r;
int ans;
int len;
int cnt;
void find(int n)
{
for(int i=2;i<=n;i++)
{
if(!vis[i])
{
prime[++cnt]=i;
s[i]=i;
}
for(int j=1;j<=cnt&&prime[j]*i<=n;j++)
{
vis[i*prime[j]]=1;
s[i*prime[j]]=prime[j];
if(i%prime[j]==0)
{
break;
}
}
}
}
bool check(int l,int r,int L,int R)
{
if((h[r]-h[l-1]*k[r-l+1]==h[R]-h[L-1]*k[R-L+1])&&(((((g[r]-g[l-1]*m[r-l+1]%mod)%mod)+mod)%mod)==((((g[R]-g[L-1]*m[R-L+1]%mod)%mod)+mod)%mod)))
{
return true;
}
return false;
}
int main()
{
scanf("%d",&n);
scanf("%s",ch+1);
find(n);
m[0]=1;
k[0]=1;
for(int i=1;i<=n;i++)
{
h[i]=h[i-1]*base+ch[i];
k[i]=k[i-1]*base;
g[i]=(g[i-1]*base%mod+ch[i])%mod;
m[i]=m[i-1]*base%mod;
}
scanf("%d",&q);
while(q--)
{
scanf("%d%d",&l,&r);
len=r-l+1;
ans=len;
for(int i=len;i>1;i/=s[i])
{
int num=ans/s[i];
if(check(l,r-num,l+num,r))
{
ans=num;
}
}
printf("%d\n",ans);
}
}

  

BZOJ2795&2890&3647[Poi2012]A Horrible Poem——hash的更多相关文章

  1. BZOJ2795/2890/3647 [Poi2012]A Horrible Poem 【字符串hash】

    题目链接 BZOJ2795 BZOJ2890 BZOJ3647 题解 三倍经验! 我们要快速求区间最小循环节 我们知道循环节有如下性质: ①当\(L\)为循环节长度,那么\(s[l...r - L] ...

  2. 【BZOJ2795】[Poi2012]A Horrible Poem hash

    [BZOJ2795][Poi2012]A Horrible Poem Description 给出一个由小写英文字母组成的字符串S,再给出q个询问,要求回答S某个子串的最短循环节.如果字符串B是字符串 ...

  3. BZOJ 2795: [Poi2012]A Horrible Poem( hash )

    ...字符串hash. 假如长度x是一个循环节, 那么对于任意n(x | n)也是一个循环节. 设当前询问区间[l, r]长度为len = ∏piai, 最终答案ans = ∏piai' ,我们只需枚 ...

  4. bzoj 2795 [Poi2012]A Horrible Poem hash+数论

    2795: [Poi2012]A Horrible Poem Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 640  Solved: 322[Subm ...

  5. 【bzoj2795】[Poi2012]A Horrible Poem Hash+分解质因数

    题目描述 给出一个由小写英文字母组成的字符串S,再给出q个询问,要求回答S某个子串的最短循环节.如果字符串B是字符串A的循环节,那么A可以由B重复若干次得到. 输入 第一行一个正整数n (n<= ...

  6. [POI2012]OKR-A Horrible Poem hash

    题面:洛谷 题解: 首先我们需要知道一个性质,串s的最小循环节 = len - next[len].其中next[len]表示串s的一个最长长度使得s[1] ~ s[next[len]] == s[l ...

  7. bzoj 2795 [Poi2012]A Horrible Poem hash+线性筛

    题目大意 bzoj 2795 给出一个由小写英文字母组成的字符串S,再给出q个询问,要求回答S某个子串的最短循环节. 如果字符串B是字符串A的循环节,那么A可以由B重复若干次得到. n<=500 ...

  8. P3538 [POI2012]OKR-A Horrible Poem

    P3538 [POI2012]OKR-A Horrible Poem hash+线性筛 题解 <----这篇写的不错(其实是我懒得码字了qwq) UVA10298 Power Strings 的 ...

  9. [BZOJ2795][Poi2012]A Horrible Poem

    2795: [Poi2012]A Horrible Poem Time Limit: 50 Sec  Memory Limit: 128 MBSubmit: 261  Solved: 150[Subm ...

随机推荐

  1. android RadioGroup中设置selector后出现多个别选中的RadioButton的解决办法

    在一个RadioGroup组中假如有三个或者以上的RadioButton,当然你需要给这些RadioButton设置selector.设置其中的一个为默认选中状态(在xml中设置).当程序在手机上运行 ...

  2. linux调度器源码分析 - 运行(四)

    本文为原创,转载请注明:http://www.cnblogs.com/tolimit/ 引言 之前的文章已经将调度器的数据结构.初始化.加入进程都进行了分析,这篇文章将主要说明调度器是如何在程序稳定运 ...

  3. Crowdsourcing[智能辅助标注]

    为了实现标注平台智能辅助标注的能力,即上传一个标注任务,开始不提供辅助任务,随着用户标注的进行,后台可以收集一部分的标记数据,然后开启模型训练,并接着提供模型服务功能.然后再收集数据,再不断的训练,然 ...

  4. CDH hive-1.1.0-cdh5.10.0 安装

    又重新安装Hive,记录一下吧: hadoop早已经装上了. cdh5的hive下载地址: http://archive.cloudera.com/cdh5/cdh/5/ 下载文件:hive-1.1. ...

  5. 小程序学习-iPhone X适配

    一.  安全区域(safe area) 与iPhone6/6s/7/8相比,iPhone X 无论是在屏幕尺寸.分辨率.甚至是形状上都发生了较大的改变,下面以iPhone 8作为参照物,先看看iPho ...

  6. 重装系统之无法在驱动器0的分区1上安装windows

    在通过U盘或光盘安装win8/win8.1/win10 时,遇到无法安装的问题,提示“无法在驱动器0的分区1上安装windows”,格式化分区也不能解决,进而提示Windows无法安装到这个磁盘,选中 ...

  7. .Net并行编程(一)-TPL之数据并行

    前言 许多个人计算机和工作站都有多个CPU核心,可以同时执行多个线程.利用硬件的特性,使用并行化代码以在多个处理器之间分配工作. 应用场景 文件批量上传 并行上传单个文件.也可以把一个文件拆成几段分开 ...

  8. ABP module-zero +AdminLTE+Bootstrap Table+jQuery权限管理系统第十五节--缓存小结与ABP框架项目中 Redis Cache的实现

    返回总目录:ABP+AdminLTE+Bootstrap Table权限管理系统一期 缓存 为什么要用缓存 为什么要用缓存呢,说缓存之前先说使用缓存的优点. 减少寄宿服务器的往返调用(round-tr ...

  9. linux RPM manager

    RPM manage:rpm2cpio package_name | cpio -id #将一个rpm包解压至当前目录rpm -qi package_name #查看一个已安装的rpm包信息rpm - ...

  10. [转载]sql 盲注之正则表达式攻击

    [转载]sql 盲注之正则表达式攻击 -----------------------------------------MYSQL 5+-------------------------------- ...