1. 程式人生 > >bzoj2160 拉拉隊排練

bzoj2160 拉拉隊排練

降序排序 ret define 範圍 我只 images tac pri stdout

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個測試點,數據範圍滿足:

技術分享

正解:回文自動機。

回文自動機板子,所以我只是來復習一下的。。然而此題坑點巨多。。

 1 //It is made by wfj_2048~
 2 #include <algorithm>
 3 #include <iostream>
 4 #include <complex>
 5 #include <cstring>
 6 #include <cstdlib>
 7 #include <cstdio>
 8 #include <vector>
 9 #include <cmath>
10
#include <queue> 11 #include <stack> 12 #include <map> 13 #include <set> 14 #define rhl (19930726) 15 #define N (1000010) 16 #define il inline 17 #define RG register 18 #define ll long long 19 #define File(s) freopen(s".in","r",stdin),freopen(s".out","w",stdout) 20 21 using namespace std; 22 23 int ch[N][26],len[N],fail[N],st[N],n,la,sz,cnt; 24 ll val[N],k,res,ans; 25 char s[N]; 26 27 il ll gi(){ 28 RG ll x=0,q=1; RG char ch=getchar(); 29 while ((ch<0 || ch>9) && ch!=-) ch=getchar(); 30 if (ch==-) q=-1,ch=getchar(); 31 while (ch>=0 && ch<=9) x=x*10+ch-48,ch=getchar(); 32 return q*x; 33 } 34 35 il int cmp(const int &a,const int &b){ return len[a]>len[b]; } 36 37 il ll qpow(RG ll a,RG ll b){ 38 RG ll ans=1; 39 while (b){ 40 if (b&1) ans=ans*a%rhl; 41 a=a*a%rhl,b>>=1; 42 } 43 return ans; 44 } 45 46 il void insert(RG int c,RG int n){ 47 RG int x=la; while (s[n-len[x]-1]!=s[n]) x=fail[x]; 48 if (!ch[x][c]){ 49 RG int v=++sz,k=fail[x]; len[v]=len[x]+2; 50 while (s[n-len[k]-1]!=s[n]) k=fail[k]; 51 fail[v]=ch[k][c],ch[x][c]=v; 52 } 53 la=ch[x][c],++val[ch[x][c]]; return; 54 } 55 56 il void work(){ 57 n=gi(),k=gi(),scanf("%s",s+1),len[++sz]=-1,fail[0]=1; 58 for (RG int i=1;i<=n;++i) insert(s[i]-97,i); 59 for (RG int i=sz;i>1;--i) val[fail[i]]+=val[i]; 60 for (RG int i=2;i<=sz;++i) if (len[i]&1) st[++cnt]=i,res+=val[i]; 61 if (res<k){ puts("-1"); return; } res=0,ans=1,sort(st+1,st+cnt+1,cmp); 62 for (RG int i=1;i<=cnt;++i) 63 if (res+val[st[i]]>=k){ ans=ans*qpow(len[st[i]],k-res)%rhl; break; } 64 else res+=val[st[i]],ans=ans*qpow(len[st[i]],val[st[i]])%rhl; 65 printf("%lld\n",ans); return; 66 } 67 68 int main(){ 69 File("team"); 70 work(); 71 return 0; 72 }

bzoj2160 拉拉隊排練