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;
}

  

原文地址:https://www.cnblogs.com/y2823774827y/p/10102309.html