传送门


先不考虑”不是连续的一段“这一个约束条件。可以知道:第$i$位与第$j$位相同,可以对第$\frac{i+j}{2}$位置上产生$1$的贡献(如果$i+j$为奇数表明它会对一条缝产生$1$的贡献),而每一个位置上或缝上的满足条件的字符串的个数就是$2^\text{贡献}-1$。把$\frac{1}{2}$忽略掉,也就是说:第$i$位与第$j$位相同时会在第$i+j$位产生$1$的贡献。这个是经典的生成函数+$FFT$求解的问题。具体来说,将$a,b$两个字母分开计算,以计算$a$的贡献为例,如果第$i$位上为$a$,则两个多项式的$x^i$项的系数为$1$,否则为$0$,然后将两个多项式做卷积得到的结果的每一项的系数就是$a$字母对每一位做的贡献,$b$同理。

然后我们考虑减掉连续的一段。连续的一段就是一段回文串,使用$Manacher$求解即可。

#include<bits/stdc++.h>
#define ld long double
//This code is written by Itst
using namespace std;

inline int read(){
    ;
    ;
    char c = getchar();
    while(c != EOF && !isdigit(c)){
        if(c == '-')
            f = ;
        c = getchar();
    }
    while(c != EOF && isdigit(c)){
        a = (a << ) + (a << ) + (c ^ ');
        c = getchar();
    }
    return f ? -a : a;
}

 , MOD = 1e9 + ;
] , news[MAXN];
struct comp{
    ld x , y;

    comp(ld _x =  , ld _y = ){
        x = _x;
        y = _y;
    }

    comp operator +(comp a){
        return comp(x + a.x , y + a.y);
    }

    comp operator -(comp a){
        return comp(x - a.x , y - a.y);
    }

    comp operator *(comp a){
        return comp(x * a.x - y * a.y , x * a.y + y * a.x);
    }
}A[MAXN];
int need , dir[MAXN] , calc[MAXN] , manacher[MAXN];
);

inline int poww(long long a , int b){
    ;
    while(b){
        )
            times = times * a % MOD;
        a = a * a % MOD;
        b >>= ;
    }
    return times;
}

inline void swap(comp& a , comp& b){
    comp t = a;
    a = b;
    b = t;
}

inline void FFT(int type){
    comp wn , w;
     ; i < need ; ++i)
        if(i < dir[i])
            swap(A[i] , A[dir[i]]);
     ; i < need ; i <<= ){
        wn = comp(cos(pi / i) , type * sin(pi / i));
         ; j < need ; j += i << ){
            w = comp( , );
             ; k < i ; ++k , w = w * wn){
                comp x = A[j + k] , y = A[i + j + k] * w;
                A[j + k] = x + y;
                A[i + j + k] = x - y;
            }
        }
    }
}
int main(){
#ifndef ONLINE_JUDGE
    freopen("4199.in" , "r" , stdin);
    //freopen("4199.out" , "w" , stdout);
#endif
    scanf("%s" , s);
    ;
    need = ;
    )
        need <<= ;
     ; i < need ; ++i)
        dir[i] = (dir[i >> ] >> ) | (i &  ? need >>  : );

     ; i < l ; ++i)
        if(s[i] == 'a')
            A[i].x = ;
    FFT();
     ; i < need ; ++i)
        A[i] = A[i] * A[i];
    FFT(-);
     ; i < need ; ++i)
        calc[i] = A[i].x / need /  + 0.6;

    memset(&A ,  , sizeof(A));
     ; i < l ; ++i)
        if(s[i] == 'b')
            A[i].x = ;
    FFT();
     ; i < need ; ++i)
        A[i] = A[i] * A[i];
    FFT(-);
     ; i < need ; ++i){
        calc[i] += A[i].x / need /  + 0.6;
        sum = (sum + poww( , calc[i]) - ) % MOD;
    }

     ; i < l ; ++i)
        news[(i << ) + ] = s[i];
     , maxI = ;
     ; i < l <<  ; ++i){
        if(maxD > i)
            manacher[i] = min(manacher[maxI *  - i] , maxD - i - );
         && i + manacher[i] <= l <<  && news[i - manacher[i]] == news[i + manacher[i]])
            ++manacher[i];
        sum = (sum - (manacher[i] >> ) + MOD) % MOD;
        if(i + manacher[i] > maxD){
            maxD = i + manacher[i];
            maxI = i;
        }
    }
    cout << sum;
    ;
}

Luogu4199 万径人踪灭 FFT、Manacher的更多相关文章

  1. BZOJ 3160: 万径人踪灭 [fft manacher]

    3160: 万径人踪灭 题意:求一个序列有多少不连续的回文子序列 一开始zz了直接用\(2^{r_i}-1\) 总-回文子串 后者用manacher处理 前者,考虑回文有两种对称形式(以元素/缝隙作为 ...

  2. BZOJ3160:万径人踪灭(FFT,Manacher)

    Solution $ans=$回文子序列$-$回文子串的数目. 后者可以用$manacher$直接求. 前者设$f[i]$表示以$i$为中心的对称的字母对数. 那么回文子序列的数量也就是$\sum_{ ...

  3. P4199 万径人踪灭 FFT + manacher

    \(\color{#0066ff}{ 题目描述 }\) \(\color{#0066ff}{输入格式}\) 一行,一个只包含a,b两种字符的字符串 \(\color{#0066ff}{输出格式}\) ...

  4. BZOJ 3160: 万径人踪灭 FFT+快速幂+manacher

    BZOJ 3160: 万径人踪灭 题目传送门 [题目大意] 给定一个长度为n的01串,求有多少个回文子序列? 回文子序列是指从原串中找出任意个,使得构成一个回文串,并且位置也是沿某一对称轴对称. 假如 ...

  5. BZOJ3160 万径人踪灭 【fft + manacher】

    题解 此题略神QAQ orz po神牛 由题我们知道我们要求出: 回文子序列数 - 连续回文子串数 我们记为ans1和ans2 ans2可以用马拉车轻松解出,这里就不赘述了 问题是ans1 我们设\( ...

  6. 万径人踪灭(FFT+manacher)

    传送门 这题--我觉得像我这样的菜鸡选手难以想出来-- 题目要求求出一些子序列,使得其关于某个位置是对称的,而且不能是连续一段,求这样的子序列的个数.这个直接求很困难,但是我们可以先求出所有关于某个位 ...

  7. bzoj 3160: 万径人踪灭【FFT+manacher】

    考虑正难则反,我们计算所有对称子序列个数,再减去连续的 这里减去连续的很简单,manacher即可 然后考虑总的,注意到关于一个中心对称的两点下标和相同(这样也能包含以空位为对称中心的方案),所以设f ...

  8. 洛谷P4199 万径人踪灭(manacher+FFT)

    传送门 题目所求为所有的不连续回文子序列个数,可以转化为回文子序列数-回文子串数 回文子串manacher跑一跑就行了,考虑怎么求回文子序列数 我们考虑,如果$S_i$是回文子序列的对称中心,那么只要 ...

  9. BZOJ3160 万径人踪灭(FFT+manacher)

    容易想到先统计回文串数量,这样就去掉了不连续的限制,变为统计回文序列数量. 显然以某个位置为对称轴的回文序列数量就是2其两边(包括自身)对称相等的位置数量-1.对称有啥性质?位置和相等.这不就是卷积嘛 ...

随机推荐

  1. Apex单元测试

    单元测试类 Salesforce中为Apex语言提供了完整的单元测试流程,包括单元测试类.测试的运行和结果分析等. 单元测试类是一种特殊的Apex类,基本语法和普通的Apex类一样. 单元测试类的结构 ...

  2. Jenkins 利用Dashboard View插件管理任务视图

    利用Dashboard View插件管理任务视图   by:授客 QQ:1033553122 步骤 1.  安装Dashboard View插件 说明: 如果无法在线安装,可以选择本地上传方式安装 附 ...

  3. (网页)JS和CSS不缓存方法,时间戳

    <link ..... href=".....css?time"+new Date()> <script type="text/javascript&q ...

  4. JMeter—定时器(八)

    参考<全栈性能测试修炼宝典JMeter实战>第六章 JMeter 元件详解中第三节定时器 JMeter中的定时器一般用来设置延迟与同步.定时器的执行优先级高于取样器,在同一作用域下有多个定 ...

  5. python第八十八天----dom js

    DOM操作 1. 找到标签直接查找 document.getElementById 根据ID获取一个标签 document.getElementsByName 根据name属性获取标签集合 docum ...

  6. 视频截图Util

    ​​ VideoToPicUtil.java package com.zhwy.util; import java.io.File; import java.util.ArrayList; impor ...

  7. LDAP Filter用法

    #根据Pager过滤域用户 $pagers = gc D:\Operations\tmp\u.txt foreach ($p in $pagers) { $user = Get-ADUser -Fil ...

  8. 什么是Docker?

      概观 Docker是推动集装箱运动的公司,也是唯一一家能够解决混合云中的每个应用的集装箱平台提供商.当今的企业面临数字化转型的压力,但受到现有应用程序和基础架构的制约,同时合理化日益多样化的云,数 ...

  9. 3.2Python数据处理篇之Numpy系列(二)--- ndarray数组的创建与变换

    目录 (一)ndarray数组的创建 1.从列表以元组中创建: 2.使用函数创建: (二)ndarray数组的变换 1.维度的变换: 2.类型的变换: 目录: 1.ndarray数组的创建 2.nda ...

  10. SQLite基本操作-----IOS(如有雷同,纯属巧合)

    一.常用方法 sqlite3          *db, 数据库句柄,跟文件句柄FILE很类似 sqlite3_stmt      *stmt, 这个相当于ODBC的Command对象,用于保存编译好 ...