【BZOJ 2160】 拉拉队排练

【题目链接】

            https://www.lydsy.com/JudgeOnline/problem.php?id=2160

【算法】

           先简化题意 : 给定一个字符串,求最长的k个奇回文子串长度的乘积

           先运行Manacher算法,对于每个位置i,我们知道以i为中心的回文串的最长半径为pi,那么i这个位置对半径为1-p[i]的回文串的个数都产生了1的”贡献“

           因此,我们可以用差分求出任意半径的回文串个数,然后统计答案即可,注意要用快速幂

【代码】

           

#include<bits/stdc++.h>
using namespace std;
#define MAXN 1000010
const int P = 19930726;
typedef long long ll;

int i,len,n;
ll sum,ans,k;
int p[MAXN];
ll cnt[MAXN];
char s[MAXN];

inline ll power(ll a,ll n)
{
        ll ans = 1,b = a;
        while (n)
        {
                if (n & 1) ans = 1ll * ans * b % P;
                n >>= 1;
                b = 1ll * b * b % P;
        }    
        return ans;
}
    
inline void Manacher()
{
        int i,pos = 0,mx = 0;
        for (i = 1; i <= len; i++)    
        {
                if (mx > i)    p[i] = min(p[2*pos-i],mx-i);
                else p[i] = 1;
                while (i - p[i] >= 1 && i + p[i] <= len && s[i-p[i]] == s[i+p[i]]) p[i]++;
                if (i + p[i] - 1 > mx)
                {
                        mx = i + p[i] - 1;
                        pos = i;        
                } 
        }    
}

int main() 
{
        
        scanf("%d%lld%s",&n,&k,s+1);
        len = strlen(s+1);
        Manacher();
        for (i = 1; i <= len; i++)
        {
                cnt[1]++;
                cnt[p[i]+1]--;        
        }
        for (i = 1; i <= (len + 1) / 2; i++) cnt[i] += cnt[i-1];
        sum = 0; ans = 1;
        for (i = (len + 1) / 2; i >= 1; i--)
        {
                if (cnt[i] <= 0) continue;
                if (sum + cnt[i] < k) 
                {
                        sum += cnt[i];
                        ans = 1ll * ans * power(2*i-1,cnt[i]) % P;
                } else
                {
                        ans = 1ll * ans * power(2*i-1,k-sum) % P;
                        sum += cnt[i];
                        break; 
                }
        }
        if (sum < k) printf("-1\n");
        else printf("%lld\n",ans);
        
        return 0;
     
}

 

posted @ 2018-07-01 09:31  evenbao  阅读(90)  评论(0编辑  收藏  举报