zoukankan      html  css  js  c++  java
  • luoguP1659 [国际集训队]拉拉队排练 manacher算法

    直接统计长度为$i$的回文子串有多少个

    然后倒叙枚举长度,快速幂统计一下即可

    复杂度$O(n log n)$

    #include <cstdio>
    #include <cstring>
    #include <iostream>
    #include <algorithm>
    using namespace std;
    
    #define ll long long
    #define ri register int
    #define rep(io, st, ed) for(ri io = st; io <= ed; io ++)
    #define drep(io, ed, st) for(ri io = ed; io >= st; io --)
        
    const int sid = 1000005;
    const int mod = 19930726;
    
    inline void inc(int &a, int b) { a += b; if(a >= mod) a -= mod; }
    inline void dec(int &a, int b) { a -= b; if(a < 0) a += mod; }
    inline int mul(int a, int b) { return 1ll * a * b % mod; }
    inline int fp(int a, int k) {
        int ret = 1;
        for( ; k; k >>= 1, a = mul(a, a))
            if(k & 1) ret = mul(ret , a);
        return ret;
    }
    
    ll n, k;
    char s[sid];
    int r[sid], num[sid];
    
    int main() {
        cin >> n >> k;
        scanf("%s", s + 1);
        int mr = 1, pos = 1; r[1] = 1;
        rep(i, 2, n) {
            r[i] = min(mr - i + 1, r[pos + pos - i]);
            while(i - r[i] > 0 && s[i + r[i]] == s[i - r[i]]) r[i] ++;
            if(i + r[i] - 1 > mr) mr = i + r[i] - 1, pos = i;
        }
        rep(i, 1, n) num[2 * r[i] - 1] ++;
        drep(i, n, 1) num[i] += num[i + 1];
        
        int ans = 1;
        drep(i, n, 1)
        if(i & 1) {
            if(k >= num[i]) {
                ans = mul(ans, fp(i, num[i]));
                k -= num[i];
            }
            else {
                ans = mul(ans, fp(i, k));
                break;
            }
        }
        
        printf("%d
    ", ans);
        return 0;
    }
  • 相关阅读:
    数组字符串
    return语句
    函数
    js流程控制语句
    js数据类型
    精进:如何成为一个很厉害的人---书摘(转)
    生成随机的数字和字母组合
    modelAndView重定向到外网
    mysql. 替换数据库中某个字段
    java中对于时间的处理
  • 原文地址:https://www.cnblogs.com/reverymoon/p/9964680.html
Copyright © 2011-2022 走看看