2160: 拉拉队排练

来源:互联网 发布:淘宝卖家聊天软件 编辑:程序博客网 时间:2024/04/29 19:37

2160: 拉拉队排练

Time Limit: 10 Sec  Memory Limit: 259 MB
Submit: 1016  Solved: 395
[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个测试点,数据范围满足: 

Source

[Submit][Status][Discuss]



先弄个Manacher求出所有的回文半径

因为一个长度为k的回文串很显然包含长度为k-2的回文串

开个桶,快速幂弄一弄就行了

#include<iostream>#include<cstdio>#include<queue>#include<vector>#include<bitset>#include<algorithm>#include<cstring>#include<map>#include<stack>#include<set>#include<cmath>#include<ext/pb_ds/priority_queue.hpp>using namespace std;const int maxn = 1E6 + 10;typedef long long LL;const LL mo = 19930726;int n,len,pos,co[maxn],r[maxn*2];char ch[maxn],a[maxn*2];LL ans = 1,tot,k;LL ksm(LL x,int y){LL ret = 1;for (; y; y >>= 1) {if (y&1) ret = ret*x%mo;x = x*x%mo;}return ret;}int main(){#ifdef DMCfreopen("DMC.txt","r",stdin);#endifcin >> n >> k;scanf("%s",ch + 1);for (int i = 1; i <= n; i++) a[i*2-1] = ch[i];n *= 2;r[0] = 1; pos = 0;for (int i = 1; i <= n; i++) {if (pos + r[pos] - 1 < i) {int now = 1;while (i >= now && a[i+now] == a[i-now]) ++now;r[i] = now; pos = i;}else {int j = 2*pos - i;if (i + r[j] < pos + r[pos]) r[i] = r[j];else {int now = pos + r[pos] - i;while (i >= now && a[i+now] == a[i-now]) ++now;r[i] = now; pos = i;}}}for (int i = 1; i <= n; i += 2) {int Add = (r[i]&1)?1:0;int K = r[i]/2 + Add;K = K*2 - 1;++co[K];}n /= 2;for (int i = n; i; i--) {if (tot + co[i] >= k) {ans *= ksm(i,k - tot); ans %= mo; cout << ans;return 0;}else {ans *= ksm(i,co[i]); tot += 1LL*co[i];ans %= mo; if (i >= 2) co[i-2] += co[i];}}if (tot < k) cout << -1; else cout << ans;return 0;}

0 0
原创粉丝点击