• 【bzoj2795】【Poi2012】A Horrible Poem


    • 题解:

      • 询问区间的整循环节
      • 设区间长度为$n$
      • 果有循环节长为$x$和$y$,那由斐蜀定理得$gcd(x,y)$也一定为一个循环节;
      • 假设最小的循环节长为$mn$,那么对于任何循环节长$x$,一定$mn | x$ , 否则$gcd(mn,x)<mn$矛盾
      • 推出$frac{n}{x} | frac{n}{mn}$
      • 所以每次提出$n$的一个质因子$p$,考虑是否可以分成$p$段,如果可以$n=frac{n}{p}$继续找;
      • 最后得出来的$n$就是最短的循环节;
      • 分解质因子可以$O(n)$线筛最大/最小质因子,$O(logn)$分解;
      •  1 #include<bits/stdc++.h>
         2 #define rg register
         3 #define il inline 
         4 #define ull unsigned long long
         5 #define base 1234567891
         6 using namespace std;
         7 const int N=500010;
         8 int vis[N],pr[N],pt,v[N],n,m,len;
         9 ull pw[N],h[N];
        10 char gc(){
        11     static char*p1,*p2,s[1000000];
        12     if(p1==p2)p2=(p1=s)+fread(s,1,1000000,stdin);
        13     return(p1==p2)?EOF:*p1++;
        14 }
        15 int rd(){
        16     int x=0;char c=gc();
        17     while(c<'0'||c>'9')c=gc();
        18     while(c>='0'&&c<='9')x=(x<<1)+(x<<3)+c-'0',c=gc();
        19     return x;
        20 }
        21 void pre(){
        22     for(rg int i=2;i<=n;i++){
        23         if(!vis[i])pr[++pt]=i,v[i]=i;
        24         for(rg int j=1,t;j<=pt&&pr[j]*i<=n;j++){
        25             vis[t=i*pr[j]]=1;
        26             v[t]=pr[j];
        27             if(i%pr[j]==0)break;
        28         }
        29     }
        30 }
        31 ull cal(int i,int j){return h[i+j-1] - h[i-1]*pw[j];}
        32 int main(){
        33     #ifndef ONLINE_JUDGE
        34     freopen("bzoj2795.in","r",stdin);
        35     freopen("bzoj2795.out","w",stdout);
        36     #endif
        37     n=rd(); pre();
        38     char ch=gc();while(!isalpha(ch))ch=gc();
        39     for(rg int i=pw[0]=1;i<=n;i++,ch=gc()){
        40         h[i]=h[i-1]*base+ch;
        41         pw[i]=pw[i-1]*base;
        42     } 
        43     m=rd();
        44     for(rg int i=1,l,r;i<=m;i++){
        45         l=rd(); r=rd();
        46         int ans=r-l+1,now=ans,t;
        47         while(now>1){
        48             t=ans/v[now];
        49             if(cal(l,ans-t)==cal(l+t,ans-t))ans/=v[now];
        50             now/=v[now];
        51         }
        52         printf("%d
        ",ans);
        53     } 
        54     return 0;
        55 }
        bzoj2795
  • 相关阅读:
    C#编写功能让你的系统导入注册表文件时不提示
    登陆框提示历史记录
    C# 操作系统防火墙
    C# 制作Java +Mysql+Tomcat 环境安装程序,一键式安装 (续集Tomcat 配置)
    C# 修饰符你记住了吗?
    C# 实现设置系统环境变量设置
    showModalDialog使用例子,父窗口向子窗口传递值
    C#后台无刷新页面弹出alert方法
    VS2008 无法启动调试.未安装Silverlight托管调试包 .
    在GridView中使用FindControl .
  • 原文地址:https://www.cnblogs.com/Paul-Guderian/p/10241556.html
Copyright © 2020-2023  润新知