1. 程式人生 > >[BZOJ2160]拉拉隊排練

[BZOJ2160]拉拉隊排練

include 舞技 con str sin 優秀 題解 16px 字符

2160: 拉拉隊排練

Time Limit: 10 Sec Memory Limit: 259 MB
Submit: 1881 Solved: 728
[Submit][Status][Discuss]

Description

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

Input

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

Output

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

Sample Input

5 3
ababa

Sample Output

45
【樣例說明】
和諧小群體女生所拿牌子上寫的字母從左到右按照女生個數降序排序後為ababa, aba, aba, bab, a, a, a, b, b,前三個長度的乘積為。

HINT

總共20個測試點,數據範圍滿足: 技術分享

題目大意:求前k大長回文串的長度乘積

題解:Manacher+枚舉

代碼:

#include<iostream>
#include<cstdio>
#include<cstring>
#define maxn 1000009
#define mod 19930726
#define LL long long 
using namespace std;

int m,n;
char s[maxn];
LL Len[maxn],cnt[maxn];
LL k,ans=1;

LL ksm(LL a,LL b){
    LL ret=1;
    while
(b){ if(b&1)ret=ret*a%mod; a=a*a%mod; b>>=1; } return ret; } void Manacher(){ LL mx=0,id; for(int i=1;i<=n;i++){ if(mx>i)Len[i]=min(mx-i,Len[2*id-i]); else Len[i]=1; while(s[i-Len[i]]==s[i+Len[i]])Len[i]++; if(i+Len[i]>mx)mx=i+Len[i],id=i; } } int main(){ scanf("%d%lld",&n,&k); scanf("%s",s+1);s[0]=$; Manacher(); for(int i=1;i<=n;i++)cnt[2*Len[i]-1]++; for(int i=n;i>=1;i--){ if(cnt[i]){ LL g=min(k,cnt[i]); ans=(ans%mod*ksm(i,g)%mod)%mod; k-=g; if(!k)break; cnt[i-2]+=cnt[i]; } } if(k)puts("-1\n"); else printf("%lld\n",ans); return 0; }

[BZOJ2160]拉拉隊排練