bzoj2160: 拉拉队排练

来源:互联网 发布:程序员的思维修炼 mobi 编辑:程序博客网 时间:2024/04/29 18:37

//  如果去看这一题的提交状况,PE总共有4发,傻逼我贡献了3发..bzoj好有爱,I64d和lld这种返回PE,不是WA,要不然要被坑出翔了。

      

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,前三个长度的乘积为。
<span style="color: blue; font-family: arial, verdana, helvetica, sans-serif; font-size: 12px; background-color: rgb(255, 255, 255);">HINT</span>



     我的思路是,枚举每个点,假设以这个点为中心的最长回文串的长度为p,则存在长度为1-p的回文串,则每个长度的值加上1,当然这么做会TLE。稍微分析一下发现,譬如我们要求长度为1的回文串数量,那么只要枚举到最长回文串长度>1的点,num[1]++,即num[1]等于>=1的回文串数量之和,然后我用上了树状数组。
代码如下

#include "stdio.h"#include "string.h"#include "algorithm"#define MAX 1000000#define MOD 19930726using namespace std;char a[MAX*2+2],b[MAX*2+2];long long r[MAX*2+2];long long hash[MAX*2+2];long long sum[MAX*2+2];long long  len;long long  n,k;long long lowbit(long long x){     return x&(-x);}long long modify(long long p,long long del){     while(p<=len)     {         sum[p]+=del;         p+=lowbit(p);     }}long long sum1(long long p){    long long res=0;    while(p)    {          res+=sum[p];          p-=lowbit(p);    }    return res;}void add(){    int i;    len=strlen(a);    b[0]='$';    b[1]='#';    for(i=0;i<len;i++)    {b[i*2+2]=a[i];     b[i*2+3]='#';    }    len=2*len+2;    b[len]='\0';}long long  min(long long  a,long long  b){    return a<b?a:b;}void manacher(){    long long  i,mx=0,p=0;    memset(r,0,sizeof(r));    for(i=0;i<len;i++)    {        if(i<mx)              r[i]=min(r[2*p-i],mx-i);        while(b[i-r[i]]==b[i+r[i]])              r[i]++;        if(i+r[i]>mx)        {            mx=i+r[i];            p=i;        }    }}long long mod(long long a,long long b,long long c){    long long ans=1;    while(b)    {        if(b&1)             ans=ans*a%MOD;        a=(a%c*a%c)%c;        b=b/2;    }    return ans;}void slove(){    int i,j;    long long ans=1;    memset(hash,0,sizeof(hash));    memset(sum,0,sizeof(sum));    add();    manacher();    for(i=1;i<len;i++)         if(b[i]!='#')              modify(r[i]-1,1);    hash[1]=sum1(n);    for(i=2;i<=n;i++)              hash[i]=sum1(n)-sum1(i-1);    //for(i=1;i<=n;i++)    //        printf("%d ",hash[i]);    //printf("\n");    for(i=n;i>=1&&k;i--)            {                  if(i%2==0||!hash[i])                        continue;                  if(hash[i]>k)                        {hash[i]=k;k=0;}                  else                        k-=hash[i];                  ans=((ans%MOD)*(mod(i,hash[i],MOD)%MOD))%MOD;              }    if(k>0)          ans=-1;    printf("%lld\n",ans);}int main(){     scanf("%lld%lld",&n,&k);    //{        scanf("%s",a);        slove();    //}    return 0;}



0 0
原创粉丝点击