1. 程式人生 > >BZOJ_2160_拉拉隊排練_manacher

BZOJ_2160_拉拉隊排練_manacher

cpp namespace 隨著 小夥子 mod -i bzoj amp sam

BZOJ_2160_拉拉隊排練_manacher

Description

艾利斯頓商學院籃球隊要參加一年一度的市籃球比賽了。拉拉隊是籃球比賽的一個看點,好的拉拉隊往往能幫助球隊增加士氣,贏得最終的比賽。所以作為拉拉隊隊長的楚雨蕁同學知道,幫助籃球隊訓練好拉拉隊有多麽的重要。拉拉隊的選拔工作已經結束,在雨蕁和校長的挑選下,n位集優秀的身材、舞技於一體的美女從眾多報名的女生中脫穎而出。這些女生將隨著籃球隊的小夥子們一起,和對手抗衡,為艾利斯頓籃球隊加油助威。一個陽光明媚的早晨,雨蕁帶領拉拉隊的隊員們開始了排練。n個女生從左到右排成一行,每個人手中都舉了一個寫有26個小寫字母中的某一個的牌子,在比賽的時候揮舞,為小夥子們吶喊、加油。雨蕁發現,如果連續的一段女生,有奇數個,並且他們手中的牌子所寫的字母,從左到右和從右到左讀起來一樣,那麽這一段女生就被稱作和諧小群體。現在雨蕁想找出所有和諧小群體,並且按照女生的個數降序排序之後,前K個和諧小群體的女生個數的乘積是多少。由於答案可能很大,雨蕁只要你告訴她,答案除以19930726的余數是多少就行了。

Input

輸入為標準輸入。第一行為兩個正整數n和K,代表的東西在題目描述中已經敘述。接下來一行為n個字符,代表從左到右女生拿的牌子上寫的字母。

Output

輸出為標準輸出。輸出一個整數,代表題目描述中所寫的乘積除以19930726的余數,如果總的和諧小群體個數小於K,輸出一個整數-1。

Sample Input

5 3
ababa

Sample Output

45


一開始看錯題了,以為要奇偶分開討論。。代碼就寫成那樣了。

本題只考慮長度為奇數的回文串。

manacher過程中求極長回文子串然後區間加差分一下。

剩下的就是模擬了。

代碼:

#include <cstdio>
#include <string.h>
#include <algorithm>
using namespace std;
typedef long long ll;
#define mod 19930726
#define N 1000050
int c[N],p[N<<1],a[N<<1],n,d[N],e[N];
char w[N<<1];
ll K;
ll qp(ll x,ll y) {
    ll re=1; for(;y;y>>=1ll,x=x*x%mod) if(y&1ll) re=re*x%mod; return re;
}
int main() {
    scanf("%d%lld",&n,&K);
    int i;
    scanf("%s",w+1);
    for(i=1;i<=n;i++) a[2*i-1]=‘$‘,a[2*i]=w[i];
    n=n<<1|1; a[n]=‘$‘;
    int mx=0,lst;
    for(i=1;i<=n;i++) {
        if(i<=mx) p[i]=min(p[2*lst-i],mx-i+1);
        else p[i]=1;
        while(i-p[i]>=1&&i+p[i]<=n&&a[i-p[i]]==a[i+p[i]]) p[i]++;
        if(mx<i+p[i]-1) {mx=i+p[i]-1; lst=i;}
        int lim=(i+p[i]-2)/2-(i-p[i]+2)/2+1;
        if(i%2==0) {
            d[1]++; d[(lim+1)/2+1]--;
        }else {
            e[1]++; e[lim/2+1]--;
        }
    }
    n>>=1;
    ll sum=0;
    for(c[1]=sum=d[1],i=3;i<=n;i+=2) {
        c[i]=c[i-2]+d[(i+1)>>1]; sum+=c[i];
    }
    for(i=2;i<=n;i+=2) {
        c[i]=c[i-2]+e[i>>1];
    }
    if(sum<K) {
        puts("-1"); return 0;
    }
    ll ans=1;
    i=n; if(n%2==0) i--;
    for(;i>=1;i-=2) {
        // printf("%d\n",c[i]);
        if(K<=c[i]) {
            printf("%lld\n",ans*qp(i,K)%mod); return 0;
        }
        K-=c[i]; ans=ans*qp(i,c[i])%mod;
    }
}

BZOJ_2160_拉拉隊排練_manacher