1. 程式人生 > >[國家集訓隊]拉拉隊訓練

[國家集訓隊]拉拉隊訓練

數據 cto bre math 計算 urn write 國家 break

Manacher的題,較簡單。
先manacher一下,找到每個回文串的長度,把長度為奇數的回文串統計一下,由於manacher,每個字母只會被統計一次,就不存在重復計算。看那個數據範圍裏面巨大的K很唬人,但是復雜度和這個K關系不大。(奇醜無比堪比wwb的代碼)

//Writer : Hsz %WJMZBMR%tourist%hzwer
#include <iostream>
#include <cstring>
#include <cstdio>
#include <cmath>
#include <queue>
#include <map>
#include <set>
#include <stack>
#include <vector>
#include <cstdlib>
#include <algorithm>
#define LL long long
#define M(a,b) memset(a,b,sizeof a)
const int inf=0x3fffffff;
using std::max;
using std::min;
using std::sort;
using std::cin;
using std::cout;
using std::endl;
using std::vector;
using std::queue;
const double eps=1e-8;
int read() {
    int x=0,f=1;
    char ch=getchar();
    while(ch<'0'||ch>'9') {
        if(ch=='-')f=-1;
        ch=getchar();
    }
    while(ch>='0'&&ch<='9') {
        x=x*10+ch-'0';
        ch=getchar();
    }
    return x*f;
}
void out(int x) {
    int a[25],wei=0;
    if(x<0) putchar('-'),x=-x;
    for(; x; x/=10) a[++wei]=x%10;
    if(wei==0) {
        puts("0");
        return;
    }
    for(int j=wei; j>=1; --j) putchar('0'+a[j]);
    putchar('\n');
}
const int N=2000005,mod=19930726;
char a[N>>1],s[N];
int len,p[N],mx,id,cnt[N];
LL n,k;
void manacher() {
    for(int i=1; i<len; i++) {
        if(i<mx) p[i]=min(p[id]+id-i,p[id*2-i]);
        else p[i]=1;
        while(s[i+p[i]]==s[i-p[i]]) p[i]++;
        if(i+p[i]>mx) mx=i+p[i],id=i;
        if((p[i]-1)&1) cnt[p[i]-1]++;
    }
}
LL ksm(LL base,int z) {
    if(base==1)return 1;
    if(!z) return 1;
    LL res=1;
    while(z) {
        if(z&1) res*=base,res%=mod;
        base*=base,base%=mod;
        z>>=1;
    }
    return res;
}
int main() {
    cin>>n>>k;
    scanf("%s",a);
    len=n;
    s[0]=s[1]='!';
    for(int i=0; i<len; i++) {
        s[i*2+2]=a[i];
        s[i*2+3]='!';
    }
    len=len*2+2;
    s[len]=0;
    manacher();
    LL sum=0;
    LL ans=1;
    for(int i=n-1+(n&1); i; i-=2) {
        sum+=cnt[i];
        if(k>=sum) {
            ans=(ans*ksm(i,sum))%mod;
            k-=sum;
        } else {
            ans=(ans*ksm(i,k))%mod;
            k-=sum;
            break;
        }
    }
    cout<<ans;
    return 0;
}

[國家集訓隊]拉拉隊訓練