青橙 A1255. 拉拉队排练(陶文博)
A1255. 拉拉队排练(陶文博)
时间限制:1.0s 内存限制:512.0MB
总提交次数: AC次数: 平均分:
试题来源
2011中国国家集训队命题答辩
问题描述
艾利斯顿商学院篮球队要参加一年一度的市篮球比赛了。拉拉队是篮球比赛的一个看点,好的拉拉队往往能帮助球队增加士气,赢得最终的比赛。所以作为拉拉队队长的楚雨荨同学知道,帮助篮球队训练好拉拉队有多么的重要。
拉拉队的选拔工作已经结束,在雨荨和校长的挑选下,n位集优秀的身材、舞技于一体的美女从众多报名的女生中脱颖而出。这些女生将随着篮球队的小伙子们一起,和对手抗衡,为艾利斯顿篮球队加油助威。
一个阳光明媚的早晨,雨荨带领拉拉队的队员们开始了排练。n个女生从左到右排成一行,每个人手中都举了一个写有26个小写字母中的某一个的牌子,在比赛的时候挥舞,为小伙子们呐喊、加油。
雨荨发现,如果连续的一段女生,有奇数个,并且他们手中的牌子所写的字母,从左到右和从右到左读起来一样,那么这一段女生就被称作和谐小群体。
现在雨荨想找出所有和谐小群体,并且按照女生的个数降序排序之后,前K个和谐小群体的女生个数的乘积是多少。由于答案可能很大,雨荨只要你告诉她,答案除以19930726的余数是多少就行了。
拉拉队的选拔工作已经结束,在雨荨和校长的挑选下,n位集优秀的身材、舞技于一体的美女从众多报名的女生中脱颖而出。这些女生将随着篮球队的小伙子们一起,和对手抗衡,为艾利斯顿篮球队加油助威。
一个阳光明媚的早晨,雨荨带领拉拉队的队员们开始了排练。n个女生从左到右排成一行,每个人手中都举了一个写有26个小写字母中的某一个的牌子,在比赛的时候挥舞,为小伙子们呐喊、加油。
雨荨发现,如果连续的一段女生,有奇数个,并且他们手中的牌子所写的字母,从左到右和从右到左读起来一样,那么这一段女生就被称作和谐小群体。
现在雨荨想找出所有和谐小群体,并且按照女生的个数降序排序之后,前K个和谐小群体的女生个数的乘积是多少。由于答案可能很大,雨荨只要你告诉她,答案除以19930726的余数是多少就行了。
输入格式
输入为标准输入。
第一行为两个正整数n和K,代表的东西在题目描述中已经叙述。
接下来一行为n个字符,代表从左到右女生拿的牌子上写的字母。
第一行为两个正整数n和K,代表的东西在题目描述中已经叙述。
接下来一行为n个字符,代表从左到右女生拿的牌子上写的字母。
输出格式
输出为标准输出。
输出一个整数,代表题目描述中所写的乘积除以19930726的余数,如果总的和谐小群体个数小于K,输出一个整数-1。
输出一个整数,代表题目描述中所写的乘积除以19930726的余数,如果总的和谐小群体个数小于K,输出一个整数-1。
样例输入
5 3
ababa
ababa
样例输出
45
样例说明
和谐小群体女生所拿牌子上写的字母从左到右按照女生个数降序排序后为ababa, aba, aba, bab, a, a, a, b, b,前三个长度的乘积为 。
数据规模和约定
总共20个测试点,数据范围满足:
测试点 | n | K |
1 | 10 | 10 |
2 | 100 | 100 |
3 | 100 | 100 |
4 | 1,000 | 1,000 |
5 | 1,000 | 1,000 |
6 | 1,000 | 1,000 |
7 | 1,000 | 1,000 |
8 | 100,000 | = 1 |
9 | 100,000 | 100,000 |
10 | 100,000 | 100,000 |
11 | 100,000 | 100,000 |
12 | 100,000 | 1,000,000,000,000 |
13 | 100,000 | 1,000,000,000,000 |
14 | 100,000 | 1,000,000,000,000 |
15 | 500,000 | 1,000,000,000,000 |
16 | 500,000 | 1,000,000,000,000 |
17 | 500,000 | 1,000,000,000,000 |
18 | 1,000,000 | = 1 |
19 | 1,000,000 | 1,000,000 |
20 | 1,000,000 | 1,000,000,000,000 |
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 1000010 #define mod 19930726 using namespace std; char s[maxn]; int fail[maxn],nxt[maxn][26],str[maxn],len[maxn],cnt[maxn],sz=-1,last,n; int creat(int l){ len[++sz]=l; return sz; } void prepare(){ creat(0); creat(-1); last=0; str[0]=str[1]=-1; fail[0]=1; } int getfail(int x){ while(str[n-len[x]-1]!=str[n])x=fail[x]; return x; } void Insert(int c){ str[++n]=c; int cur=getfail(last),now; if(!nxt[cur][c]){ now=creat(len[cur]+2); fail[now]=nxt[getfail(fail[cur])][c]; nxt[cur][c]=now; } last=nxt[cur][c]; cnt[last]++; } void count(){ for(int i=sz;i>=0;i--)cnt[fail[i]]+=cnt[i]; } struct node{ int v,num; bool operator < (const node &b)const{ return v>b.v; } }a[maxn]; int tot; long long Pow(int x,int y){ long long res=1; while(y){ if(y&1)res=res*x%mod; x=1LL*x*x%mod; y>>=1; } return res; } int main(){ prepare(); long long k;cin>>k>>k; scanf("%s",s); int l=strlen(s); for(int i=0;i<l;i++)Insert(s[i]-'a'); count(); for(int i=2;i<=l+1;i++){ if(len[i]%2==0)continue; tot++; a[tot].v=len[i];a[tot].num=cnt[i]; } sort(a+1,a+tot+1); long long sum=0,ans=1; bool flag=0; for(int i=1;i<=tot;i++){ if(sum+a[i].num>k){ ans=ans*Pow(a[i].v,k-sum)%mod; flag=1; break; } ans=ans*Pow(a[i].v,a[i].num)%mod; sum+=a[i].num; } if(!flag)puts("-1"); else cout<<ans; return 0; }