zoukankan      html  css  js  c++  java
  • P1659 [国家集训队]拉拉队排练

    P1659 [国家集训队]拉拉队排练

    题目大意

    n个字符组成的字符串,求最长的k个奇回文串乘积 n<=10^6

    回文自动机暴力统计,特判一下奇偶,快速幂乱搞就行了

    My complete code: 

    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<iostream>
    using namespace std;
    typedef long long LL;
    const LL maxn=1000005;
    const LL MOD=19930726;
    struct node{
        int son[26],fail,len;
        LL val;
    }tree[maxn];
    LL len,last,nod,k,now,ans;
    LL tong[maxn],sot[maxn];
    char s[maxn];
    bool visit[maxn];
    inline void solve(){
        s[0]='#';
        tree[0].fail=1; tree[0].len=0;
        tree[1].fail=0; tree[1].len=-1;
        last=0;
        nod=1;
        
        for(LL i=1;i<=len;++i){
            while(s[i-tree[last].len-1]!=s[i])
                last=tree[last].fail;
            if(!tree[last].son[s[i]]){
                tree[++nod].len=tree[last].len+2;
                LL j=tree[last].fail;
                while(s[i-tree[j].len-1]!=s[i])
                    j=tree[j].fail;
                tree[nod].fail=tree[j].son[s[i]];
                tree[last].son[s[i]]=nod;
            }
            last=tree[last].son[s[i]];
            ++tree[last].val;
        }
    }
    inline LL pow(LL a,LL b){
        LL base=a,sum=1;;
        while(b){
            if(b&1)
                sum=sum*base%MOD;
            base=base*base%MOD;
            b>>=1;
        }
        return sum;
    }
    inline bool cmp(LL g1,LL g2){
        return g1>g2;
    }
    int main(){
        scanf("%lld%lld",&len,&k);
        scanf(" %s",s+1);
        for(LL i=1;i<=len;++i)
            s[i]-='a';
        solve();
        LL cnt=0;
        for(LL i=nod;i>=2;--i){
            tree[tree[i].fail].val+=tree[i].val;
            tong[tree[i].len]+=tree[i].val;
            if(tree[i].len&1&&!visit[tree[i].len]){
                sot[++cnt]=tree[i].len;
                visit[tree[i].len]=true;
            }
        }
        sort(sot+1,sot+1+cnt,cmp);
        ans=1;
        for(LL i=1;i<=cnt;++i)
            if(tong[sot[i]]){
        	    if(tong[sot[i]]>=k){
        		    ans=(ans*pow(sot[i],k))%MOD;
                    printf("%lld",ans);
                    return 0;
                }else{
                    ans=(ans*pow(sot[i],tong[sot[i]]))%MOD;
                    k-=tong[sot[i]];
                }
            }
        printf("-1"); 
        return 0;
    }
    

      

  • 相关阅读:
    PHP 文件上传七牛云
    Ubuntu Nginx 配置
    Ubuntu Sublime 配置
    Ubuntu Apache 域名配置
    Ubuntu Apache 配置
    LAMP 搭建
    vue函数防抖和节流
    vs code 同步
    常用软件
    vue
  • 原文地址:https://www.cnblogs.com/y2823774827y/p/10102309.html
Copyright © 2011-2022 走看看