zoukankan      html  css  js  c++  java
  • [ BZOJ 2160 ] 拉拉队排练

    (\)

    (Description)


    一个由小写字母构成的长为(N)的字符串,求前(K)长的奇数长度回文子串长度之积,对(19930726)取模后的答案。

    • (Nin [1,10^6])(Kin [1,10^{12}])

    (\)

    (Solution)


    • (Manacher)处理出所有位置的回文半径,因为答案要求奇数长度,所以不用插入特殊字符,在原串上直接跑(Manacher)就好,回文半径内的以当前点为回文中心的每一个子串都是回文串。
    • 所以开一个长度的桶,只给回文半径对应的最长子串长度打标记,显然一个标记代表着后面所有位置都(+1),所以计算的时候,一个长度的回文子串个数是长度标记的前缀和。
    • 要求的(K)非常大,快速幂处理。

    (\)

    (Code)


    #include<cmath>
    #include<cstdio>
    #include<cctype>
    #include<cstdlib>
    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #define N 1000010
    #define R register
    #define gc getchar
    #define mod 19930726
    using namespace std;
    typedef long long ll;
     
    char c,s[N];
     
    ll m,res=1,sum;
     
    int n,len[N],cnt[N];
     
    inline void init(){
      scanf("%d%lld",&n,&m);
      while(!isalpha(c=gc()));
      s[1]=c; s[0]='['; s[n+1]=']';
      for(R int i=2;i<=n;++i) s[i]=gc();
    }
     
    inline void manacher(){
      for(R int i=1,p=0,mr=0;i<=n;++i){
        len[i]=i>mr?1:min(mr-i+1,len[(p<<1)-i]);
        while(s[i-len[i]]==s[i+len[i]]) ++len[i];
        if(i+len[i]-1>mr){p=i;mr=i+len[i]-1;}
        ++cnt[(len[i]<<1)-1];
      }
    }
     
    inline ll qpow(ll x,ll t){
      ll res=1;
      while(t){
        if(t&1) (res*=x)%=mod;
        (x*=x)%=mod; t>>=1;
      }
      return res;
    }
     
    int main(){
      init();
      manacher();
      for(R int i=((n/2)<<1)+1;i>=1;i-=2){
        sum+=(ll)cnt[i];
        if(sum>=m){printf("%lld",(res*qpow(i,m))%mod);return 0;}
        (res*=qpow(i,sum))%=mod; m-=sum;
      }
      puts("-1");
      return 0;
    }
    
  • 相关阅读:
    The Django Book学习笔记 04 模板
    The Django Book学习笔记
    Python标准库 datetime
    Python %s和%r的区别
    Python转载
    Python while 1 和 while True 速度比较
    Git 时光穿梭鸡 删除文件 以及批量删除文件
    git reset soft,hard,mixed之区别深解
    Git 时光穿梭鸡 撤销修改
    Git 时光穿梭鸡 管理修改
  • 原文地址:https://www.cnblogs.com/SGCollin/p/9690070.html
Copyright © 2011-2022 走看看