BZOJ 3160 FFT+马拉车
题意显然
ans=回文子序列数目 - 回文子串数目
回文子串直接用马拉车跑出来
回文子序列一开始总是不知道怎么求 (太蠢了)
后面看了题解
构造一个神奇的卷积
(这个是我盗的图)地址
后面还有一些细节需要处理出 f[x] (f[x] 表示 x左右相等的个数)
通常我们需要的情况是 两个函数相乘 这里是s[x-i] == s[x+i] 分类讨论就行了 变成1*1=1的形式
所以要a=1 b=0 和 a=0 b=1都算一次
这里长度扩展了一倍 表示 当 i 是奇数时表示对称轴是元素 ,偶数表示对称轴是两个元素的间隔
根据二项式定理 求出每一个f[x] 的贡献 expmod ( 2, ( cnt[i] + 1 ) >> 1 ) - 1
还有最后一个细节 相减的时候要记得加上mod 再取模
#include <cstdio>
#include <cstring>
#include <queue>
#include <cmath>
#include <algorithm>
#include <set>
#include <iostream>
#include <map>
#include <stack>
#include <string>
#include <vector>
#define pi acos(-1.0)
#define eps 1e-9
#define fi first
#define se second
#define rtl rt<<1
#define rtr rt<<1|1
#define bug printf("******\n")
#define mem(a,b) memset(a,b,sizeof(a))
#define name2str(x) #x
#define fuck(x) cout<<#x" = "<<x<<endl
#define f(a) a*a
#define sf(n) scanf("%d", &n)
#define sff(a,b) scanf("%d %d", &a, &b)
#define sfff(a,b,c) scanf("%d %d %d", &a, &b, &c)
#define sffff(a,b,c,d) scanf("%d %d %d %d", &a, &b, &c, &d)
#define pf printf
#define FRE(i,a,b) for(i = a; i <= b; i++)
#define FREE(i,a,b) for(i = a; i >= b; i--)
#define FRL(i,a,b) for(i = a; i < b; i++)+
#define FRLL(i,a,b) for(i = a; i > b; i--)
#define FIN freopen("data.txt","r",stdin)
#define gcd(a,b) __gcd(a,b)
#define lowbit(x) x&-x
#define rep(i,a,b) for(int i=a;i<b;++i)
#define per(i,a,b) for(int i=a-1;i>=b;--i)
using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const int maxn = 3e5 + ;
const int maxm = maxn * ;
const int mod = 1e9 + ;
int n, m, a[maxn], b[maxn];
int len, res[maxm], mx; //开大4倍
struct cpx {
long double r, i;
cpx ( long double r = , long double i = ) : r ( r ), i ( i ) {};
cpx operator+ ( const cpx &b ) {
return cpx ( r + b.r, i + b.i );
}
cpx operator- ( const cpx &b ) {
return cpx ( r - b.r, i - b.i );
}
cpx operator* ( const cpx &b ) {
return cpx ( r * b.r - i * b.i, i * b.r + r * b.i );
}
} va[maxm], vb[maxm];
void rader ( cpx F[], int len ) { //len = 2^M,reverse F[i] with F[j] j为i二进制反转
int j = len >> ;
for ( int i = ; i < len - ; ++i ) {
if ( i < j ) swap ( F[i], F[j] ); // reverse
int k = len >> ;
while ( j >= k ) j -= k, k >>= ;
if ( j < k ) j += k;
}
}
void FFT ( cpx F[], int len, int t ) {
rader ( F, len );
for ( int h = ; h <= len; h <<= ) {
cpx wn ( cos ( -t * * pi / h ), sin ( -t * * pi / h ) );
for ( int j = ; j < len; j += h ) {
cpx E ( , ); //旋转因子
for ( int k = j; k < j + h / ; ++k ) {
cpx u = F[k];
cpx v = E * F[k + h / ];
F[k] = u + v;
F[k + h / ] = u - v;
E = E * wn;
}
}
}
if ( t == - ) //IDFT
for ( int i = ; i < len; ++i ) F[i].r /= len;
}
void Conv ( cpx a[], cpx b[], int len ) { //求卷积
FFT ( a, len, );
FFT ( b, len, );
for ( int i = ; i < len; ++i ) a[i] = a[i] * b[i];
FFT ( a, len, - );
}
void gao () {
len = ;
mx = n + m;
while ( len <= mx ) len <<= ; //mx为卷积后最大下标
for ( int i = ; i < len; i++ ) va[i].r = va[i].i = vb[i].r = vb[i].i = ;
for ( int i = ; i < n; i++ ) va[i].r = a[i]; //根据题目要求改写
for ( int i = ; i < m; i++ ) vb[i].r = b[i]; //根据题目要求改写
Conv ( va, vb, len );
for ( int i = ; i < len; ++i ) res[i] += ( LL ) floor ( va[i].r + 0.5 );
}
char Ma[maxn * ];
int Mp[maxn * ];
int Manacher ( char s[], int len ) {
int l = , ret = ;
Ma[l++] = '$';
Ma[l++] = '#';
for ( int i = ; i < len; i++ ) {
Ma[l++] = s[i];
Ma[l++] = '#';
}
Ma[l] = ;
int mx = , id = ;
for ( int i = ; i < l; i++ ) {
Mp[i] = mx > i ? min ( Mp[ * id - i], mx - i ) : ;
while ( Ma[i + Mp[i]] == Ma[i - Mp[i]] ) Mp[i]++;
if ( i + Mp[i] > mx ) {
mx = i + Mp[i];
id = i;
}
ret += Mp[i] >> , ret %= mod;
}
return ret % mod;
}
LL expmod ( LL a, LL b ) {
LL res = ;
while ( b ) {
if ( b & ) res = res * a % mod;
a = a * a % mod;
b = b >> ;
}
return res % mod;
}
char s[maxn];
int cnt[maxn];
int main() {
// FIN;
scanf ( "%s", s + );
n = m = strlen ( s + );
LL ans = , temp = Manacher ( s + , n );
n++, m++;
for ( int i = ; i < n ; i++ ) if ( s[i] == 'a' ) a[i] = , b[i] = ;
gao();
for ( int i = ; i <= * ( n - ) ; i++ ) cnt[i] += res[i];
mem ( a, ), mem ( b, ), mem ( res, );
for ( int i = ; i < n ; i++ ) if ( s[i] == 'b' ) a[i] = , b[i] = ;
gao();
for ( int i = ; i <= * ( n - ) ; i++ ) cnt[i] += res[i];
for ( int i = ; i <= * ( n - ) ; i++ )
ans = ( ans + expmod ( , ( cnt[i] + ) >> ) - ) % mod;
printf ( "%lld\n", ( ans - temp + mod ) % mod );
return ;
}
BZOJ 3160 FFT+马拉车的更多相关文章
- BZOJ 3160 FFT+Manacher
思路: 这道题思路好奇怪--. 我们先要知道关于x (x可以是间隙) 对称的有几对字母 显然暴力是n^2的 那怎么办呢 先把所有'a'看成1 'b'看成0 意外的发现 这不就是卷积嘛 再倒过来搞一搞 ...
- BZOJ 3160: 万径人踪灭 FFT+快速幂+manacher
BZOJ 3160: 万径人踪灭 题目传送门 [题目大意] 给定一个长度为n的01串,求有多少个回文子序列? 回文子序列是指从原串中找出任意个,使得构成一个回文串,并且位置也是沿某一对称轴对称. 假如 ...
- 【BZOJ 3160】 3160: 万径人踪灭 (FFT)
3160: 万径人踪灭 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1440 Solved: 799 Description Input Outp ...
- bzoj 3160 万径人踪灭——FFT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3160 似乎理解加深了. 用卷积算相同的位置:先把 a 赋成1. b 赋成0,卷积一遍:再把 ...
- bzoj 3160: 万径人踪灭 manachar + FFT
3160: 万径人踪灭 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 133 Solved: 80[Submit][Status][Discuss] ...
- BZOJ 3160: 万径人踪灭 [fft manacher]
3160: 万径人踪灭 题意:求一个序列有多少不连续的回文子序列 一开始zz了直接用\(2^{r_i}-1\) 总-回文子串 后者用manacher处理 前者,考虑回文有两种对称形式(以元素/缝隙作为 ...
- bzoj 3160 万径人踪灭 —— FFT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3160 求出关于一个位置有多少对对称字母,如果 i 位置有 f[i] 对,对答案的贡献是 2^ ...
- bzoj 3160 万径人踪灭 FFT
万径人踪灭 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1936 Solved: 1076[Submit][Status][Discuss] De ...
- bzoj 3160: 万径人踪灭【FFT+manacher】
考虑正难则反,我们计算所有对称子序列个数,再减去连续的 这里减去连续的很简单,manacher即可 然后考虑总的,注意到关于一个中心对称的两点下标和相同(这样也能包含以空位为对称中心的方案),所以设f ...
随机推荐
- js中 null, undefined, 0,空字符串,false,不全等比较
null == undefined // true null == '' // false null == 0 // false null == false // false undefined = ...
- iframe子页面position的fixed
前言: 首先说一说我昨天天的苦逼经历.中午吃饭时一同事跟我说,他做的项目嵌套iframe后,子页面的position设置fixed失效了. 经过反复询问,得知他用了两层iframe,再加上最外的父页面 ...
- maven实战读书笔记(一)
环境变量设置 MAVEN_HOME:G:\maven-3.2\apache-maven-3.2.5 Path: G:\maven-3.2\apache-maven-3.2.5\bin 其实正确的设置应 ...
- 在虚拟机下安装Ubuntu
目录: 1.安装虚拟机 2.在虚拟下安装Ubuntu 本文将按照目录分两步来讲一下在虚拟机下安装Ubuntu.第一步是安装虚拟机,第二步是在虚拟机下安装Ubuntu. 安装虚拟机 下载虚拟机链接以及激 ...
- hadoop在章鱼大数据平台下的安装与配置
本次所用的软件版本: ubuntu :14.04 Hadoop:hadoop-2.6.0-cdh5.4.5 jdk:jdk-7u75-linux-x64 Hive: Hbase: 一.配置基本环境 1 ...
- Teamproject --人员职责
职责分配: 初步分工如下: PM:林豪森 Dev:宋天舒 张迎春 黄漠源 刘翔宇 叶露婷 旦增晋美 黄敬博 Test:林豪森 宋天舒 张迎春 刘翔宇 经过团队的讨论,认为对于职责的分配,并不存在绝对的 ...
- H-ui框架制作选项卡
本案例运用H-ui框架,写了一个选项卡案例 1. html代码(固定这样写,用一个div包裹控制条tabBar和内容条tabCon) <div id="tab-index-carteg ...
- 《Spring1之 第一次站立会议(重发)》
< 第一次站立会议(重发)> 昨天,我对我们团队要做的项目进行了相关资料的查找,我找到了服务器和客户端的相关代码以及找到了把它们通信所使用TCP/IP等协议: 今天,我把找到的代码和协议资 ...
- 【转】 MATLAB下如何指定GPU资源
[转] MATLAB下如何指定GPU资源 原文链接
- react +MUI checkbox使用
PS:因项目采用MUI,故,在此所讲的checkbox组件为MUI里的checkbox 因checkbox组件里 oncheck函数没法判断复选框是否选中,故,若直接复用且通过state改变check ...