• [BZOJ 3160] 万径人踪灭


    3160: 万径人踪灭

    Time Limit: 10 Sec  Memory Limit: 256 MB
    Submit: 2662  Solved: 1447
    [Submit][Status][Discuss]

    Description

    Input

    Output

     

    Sample Input

     

    Sample Output

     

    HINT

    考虑用总回文序列数减去回文串数

    对于每个对称轴,只需要知道有多少对关于它对称然后计算

    先把$a$置为$1$,$b$置为$0$做一次卷积,然后$a$置为$0$,$b$置为$1$做一次卷积

    两次加起来再稍微处理一下就行了

    回文串数用马拉车求

    #include <bits/stdc++.h>
    using namespace std;
    const int maxn = 262144, mod = 1e9 + 7;
    const double PI = acos(-1.0);
    
    struct comp{
        double x, y;
        comp(double _x = 0, double _y = 0){
            x = _x;
            y = _y;
        }
        friend comp operator * (const comp &a, const comp &b){
            return comp(a.x * b.x - a.y * b.y, a.x * b.y + a.y * b.x);
        }
        friend comp operator + (const comp &a, const comp &b){
            return comp(a.x + b.x, a.y + b.y);
        }
        friend comp operator - (const comp &a, const comp &b){
            return comp(a.x - b.x, a.y - b.y);
        }
    }f[maxn], g[maxn];
    int rev[maxn];
    void dft(comp A[], int len, int kind){
        for(int i = 0; i < len; i++){
            if(i < rev[i]){
                swap(A[i], A[rev[i]]);
            }
        }
        comp wn, s, t, tmp;
        for(int i = 1; i < len; i <<= 1){
            wn = comp(cos(PI / i), kind * sin(PI / i));
            for(int j = 0; j < len; j += (i << 1)){
                tmp = comp(1, 0);
                for(int k = 0; k < i; k++){
                    s = A[j + k], t = tmp * A[i + j + k];
                    A[j + k] = s + t;
                    A[i + j + k] = s - t;
                    tmp = tmp * wn;
                }
            }
        }
        if(kind == -1) for(int i = 0; i < len; i++) A[i].x /= len;
    }
    void init(int &len, int n){
        int L = 0;
        for(len = 1; len < n + n - 1; len <<= 1, L++);
        for(int i = 0; i < len; i++){
            rev[i] = rev[i >> 1] >> 1 | (i & 1) << L - 1;
        }
    }
    int bin[100000 + 10];
    char str[200000 + 10];
    int slen, p[200000 + 10] = {0};
    int main(){
        scanf("%s", str);
        int n = strlen(str), len;
        init(len, n);
        for(int i = 0; i < n; i++){
            if(str[i] == 'a') f[i].x = 1;
        }
        for(int i = 0; i < n; i++){
            if(str[i] == 'b') g[i].x = 1;
        }
        dft(f, len, 1);
        dft(g, len, 1);
        for(int i = 0; i < len; i++) g[i] = g[i] * g[i] + f[i] * f[i];
        dft(g, len, -1);
        for(int i = 0; i < n; i++) g[i << 1].x++;
        bin[0] = 1;
        for(int i = 1; i <= 100000; i++){
            bin[i] = bin[i - 1] << 1;
            if(bin[i] >= mod) bin[i] -= mod; 
        }
        int ans = 0;
        for(int i = 0; i < len; i++){
            ans += bin[(int)(g[i].x + 0.5) >> 1] - 1;
            if(ans >= mod) ans -= mod; 
        }    
        for(int i = n - 1; ~i; i--){
            str[i * 2 + 2] = str[i];
            str[i * 2 + 3] = '$';
        }
        str[0] = '~'; str[1] = '$';
        slen = 2 * n + 2;
        int mr = 0, mid;
        for(int i = 1; i < slen; i++){
            if(i <= mr){
                p[i] = min(mr - i + 1, p[(mid << 1) - i]);
            }
            while(str[i + p[i]] == str[i - p[i]]) p[i]++;
            if(p[i] + i > mr) mr = p[i] + i - 1, mid = i;
            ans -= p[i] >> 1;
            if(ans < 0) ans += mod;
        }
        printf("%d
    ", ans);
        return 0;
    } 
  • 相关阅读:
    sns矩阵
    家庭博客
    媒体治国
    论坛有
    模型指向同一地址,结构体指向不同地址
    苹果开发者公司账号添加个人开发者 加入不了开发者团队
    SourceTree下载 及使用
    关于swift语言中导入OC三方类找不到头文件的解决方法
    iPhone iPad 各种控件默认高度
    iOS 基于MVC设计模式的基类设计
  • 原文地址:https://www.cnblogs.com/ruoruoruo/p/11787263.html
Copyright © 2020-2023  润新知