P3538 [POI2012]OKR-A Horrible Poem
P3538 [POI2012]OKR-A Horrible Poem
Describe:
第一行一个正整数 ,表示 的长度。
第二行n个小写英文字母,表示字符串 。
第三行一个正整数 ,表示询问次数。
下面q行每行两个正整数,表示询问字符串 的最短循环节长度。
Sol:
显然的,最短循环长度的 倍一定是 ,也就是说循环长度 一定是长度的因子。
再就因为是循环的,所以从 应该是一样的。
那么我们就可以用哈希做到
注意的是,枚举因子要从大到小枚举,另外,我们可以利用线性筛是利用枚举最小质因子的方式来记录下每个数的最小质因子,然后除一下找到最大因子,以此类推。
Code:
/*
Knowledge : Rubbish Algorithm
Work by :Gym_nastics
Time : O(AC)
*/
#include<cmath>
#include<queue>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;
const int INF=0x3f3f3f3f;
const int Mod=1e9+7;
const int Base=131;
const int N=1e6+6;
int read() {
int x=0,f=0;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) f|=(ch=='-');
for(;isdigit(ch);ch=getchar()) x=(x<<1)+(x<<3)+(ch&15);
return f?-x:x;
}
void print(int x) {
if(x<0) putchar('-'),x=-x;
if(x>9) print(x/10);
putchar(x%10+48);
}
int Prime[N],M[N],cnt,h[N],P[N];bool vis[N];
void prepare(){
for(int i=2;i<=1e6;i++){
if(!vis[i]) Prime[++cnt]=i,M[i]=i;
for(int j=1;j<=cnt&&i*Prime[j]<=1e6;j++){
vis[i*Prime[j]]=1;M[i*Prime[j]]=Prime[j];
if(!(i%Prime[j])) break;
}
}
}
char ch[N];
signed main() {
int l=read();cin>>ch+1;int Q=read();P[0]=1;prepare();
for(int i=1;i<=l;i++) h[i]=h[i-1]*Base+ch[i],P[i]=P[i-1]*Base;
while(Q--){
int l=read(),r=read(),len,ans;
ans=len=r-l+1;while(len^1){
int k=ans/M[len];len/=M[len];
if(!(h[r-k]-h[l-1]*P[r-k-l+1]^h[r]-h[l-1+k]*P[r-k-l+1])) ans=k;
}print(ans);putchar('\n');
}
return 0;
}
本文作者:Gym_nastics
本文链接:https://www.cnblogs.com/BlackDan/p/15999728.html
版权声明:本作品采用知识共享署名-非商业性使用-禁止演绎 2.5 中国大陆许可协议进行许可。
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 25岁的心里话
· 按钮权限的设计及实现