给了两条限制,但是第二条想想是没用的,直接manacher就可以减掉多余的部分了,所以要求满足第一条的方案

也不难,可以想到枚举每个中心点,计算两边有多少对距离中心相等的位置值也相等,假设有\(t\)个,那么以这个中心点为半径的就是\(2^t-1\),因为每个都可以选或不选,减去全都不选的情况

现在就要计算和每个中心点距离相等的位置对数了,显然两个位置\(a,b\)如果值相同,那么中心就是\((a+b)/2\)(如果是小数的话就是两个格子之间的)

所以就简单了,\(A(i)=[S[i]='a'],B(i)=[S[i]='b']\),这两个多项式分别平方一下,然后再算\(2^x-1\),所有这些之和就是满足第一条的方案了

#include<bits/stdc++.h>
#define il inline
#define vd void
#define mod 1000000007
typedef long long ll;
il int gi(){
int x=0,f=1;
char ch=getchar();
while(!isdigit(ch)){
if(ch=='-')f=-1;
ch=getchar();
}
while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
return x*f;
}
const double pi=acos(-1);
struct cp{
double real,imag;
cp(){}
cp(const double&r,const double&i){real=r,imag=i;}
il cp conj(){return(cp){real,-imag};}
il vd operator =(const double&b){real=b,imag=0;}
};
il cp operator +(const cp&a,const cp&b){return(cp){a.real+b.real,a.imag+b.imag};}
il cp operator -(const cp&a,const cp&b){return(cp){a.real-b.real,a.imag-b.imag};}
il cp operator *(const cp&a,const cp&b){return(cp){a.real*b.real-a.imag*b.imag,a.real*b.imag+a.imag*b.real};}
char S[200010];
int rev[1<<19];
cp A[1<<19],omg[1<<19],inv[1<<19];
il vd fft(cp*A,int n,cp*omg){
for(int i=0;i<n;++i)if(rev[i]>i)std::swap(A[i],A[rev[i]]);
for(int o=1;o<n;o<<=1)
for(cp*p=A;p!=A+n;p+=o<<1)
for(int i=0;i<o;++i){
cp t=omg[n/(o<<1)*i]*p[i+o];
p[i+o]=p[i]-t,p[i]=p[i]+t;
}
}
int t[200010];
il int pow(int x,int y){
int ret=1;
while(y){
if(y&1)ret=1ll*ret*x%mod;
x=1ll*x*x%mod;y>>=1;
}
return ret;
}
int r[200010];
int main(){
scanf("%s",S+1);int n=strlen(S+1);
int N=1,lg=0;while(N<(n+2)<<1)N<<=1,++lg;
for(int i=0;i<N;++i)rev[i]=(rev[i>>1]>>1)|((i&1)<<lg-1);
for(int i=0;i<N;++i)omg[i]=cp(cos(i*2*pi/N),sin(i*2*pi/N)),inv[i]=omg[i].conj();
for(int i=1;i<=n;++i)A[i]=S[i]=='a';
fft(A,N,omg);
for(int i=0;i<N;++i)A[i]=A[i]*A[i];
fft(A,N,inv);
for(int i=1;i<=n<<1;++i)t[i]=(int)(A[i].real/N+0.5);
for(int i=0;i<N;++i)A[i]=0;
for(int i=1;i<=n;++i)A[i]=S[i]=='b';
fft(A,N,omg);
for(int i=0;i<N;++i)A[i]=A[i]*A[i];
fft(A,N,inv);
for(int i=1;i<=n<<1;++i)t[i]+=(int)(A[i].real/N+0.5);
ll ans=0;
for(int i=1;i<=n<<1;++i)t[i]=t[i]/2+!(i&1),ans+=pow(2,t[i])-1;
for(int i=n;i;--i)S[i<<1]=S[i];
N=n<<1|1;
for(int i=1;i<=N;i+=2)S[i]='#';
S[0]='s',S[N+1]='t';
int R=1,mid=1;r[1]=1;
for(int i=2;i<=N;++i){
r[i]=1;
if(i<=R)r[i]=std::min(R-i+1,r[mid*2-i]);
while(S[i-r[i]]==S[i+r[i]])++r[i];
if(i+r[i]-1>R)mid=i,R=i+r[i]-1;
}
for(int i=1;i<=N;++i)ans-=r[i]>>1;
printf("%lld\n",(ans%mod+mod)%mod);
return 0;
}

洛咕 P4199 万径人踪灭的更多相关文章

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

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

  2. 洛咕3312 [SDOI2014]数表

    洛咕3312 [SDOI2014]数表 终于独立写出一道题了...真tm开心(还是先写完题解在写的) 先无视a的限制,设\(f[i]\)表示i的约数之和 不妨设\(n<m\) \(Ans=\su ...

  3. 洛咕 P3700 [CQOI2017]小Q的表格

    洛咕 P3700 [CQOI2017]小Q的表格 神仙题orz 首先推一下给的两个式子中的第二个 \(b\cdot F(a,a+b)=(a+b)\cdot F(a,b)\) 先简单的想,\(F(a,a ...

  4. 洛咕 P2336 [SCOI2012]喵星球上的点名

    洛咕 P2336 [SCOI2012]喵星球上的点名 先求出SA和height,一个点名串对应的就是一段区间,还有很多个点,就转化成了 有很多个区间,很多个点集,对每个区间计算和多少个点集有交,对每个 ...

  5. 洛咕 P4131 [WC2005]友好的生物

    洛咕 P4131 [WC2005]友好的生物 首先可以发现\(C\)是没有用的,可以乘进所有的权值里面做 考虑没有最后一维的限制,那么两个生物的友好值就是 \(\sum_{i=1}^k|a_i-b_i ...

  6. 洛咕 P4528 [CTSC2008]图腾

    洛咕 P4528 [CTSC2008]图腾 神题orz. 先约定abcd表示\(1\leq A<B<C<D\leq n\),而且\(y_a,y_b,y_c,y_d\)的排名正好是\( ...

  7. 洛咕P3250 [HNOI2016]网络 整体二分

    这题太神仙了必须写博客... 显然可以想到二分答案.二分一个答案mid,如果所有长度\(\geq mid\)的路径都过x,那么答案一定\(<mid\),否则答案\(\geq mid\). 那么就 ...

  8. 洛咕 P2480 [SDOI2010]古代猪文

    洛咕 P2480 [SDOI2010]古代猪文 题目是要求\(G^{\sum_{d|n}C^d_n}\). 用费马小定理\(G^{\sum_{d|n}C^d_n\text{mod 999911658} ...

  9. 洛咕 P2155 [SDOI2008]沙拉公主的困惑

    洛咕 P2155 [SDOI2008]沙拉公主的困惑 有个结论,就是如果\(gcd(a,b)=1\),那么\(gcd(a+kb,b)=1\).证明比较显然. 所以这个题目要问的\(n!\)就可以分成\ ...

随机推荐

  1. sonarQube环境搭建--常见问题及解决

    环境配置:MySQL Server 5.7     Jdk1.8 1.安装mysql数据库(默认安装一路默认到底,注意不要先新建用户账号) a) Mysql 环境变量配置: b)新增my.ini文件: ...

  2. Python 系统学习梳理_【All】

    Python学习 1. Python学习---Python安装与基础1205 2. Python学习---PyCharm的使用学习 3. Python学习---Python数据类型1206 4. Py ...

  3. GIT学习---GIT&github的使用

    GIT&github入门 版本控制的原理: 根据md5进行文件的校验[MD5的特性就是每次的输入一致则输出也一致],对于每次的修改进行一次快照 版本控制的2个功能: 版本管理  +   协作开 ...

  4. September 05th 2017 Week 36th Tuesday

    I always in the deepest despair, meet the most beautiful sunrise. 我总是在最深的绝望里遇见最美丽的惊喜. Some pessimist ...

  5. 个人技术博客二之apk反编译与加密

    根据原文郭霖大神的博客Android安全攻防战,反编译与混淆技术完全解析 本人亲测反编译真的没有什么卵用,个人纯属好奇就去搜了一下,偷窃有罪,抄袭可耻. 1.手机上的apk都是打包好的,直接安装使用. ...

  6. 原生js实现一个DIV的碰撞反弹运动

     原生js实现一个DIV的碰撞反弹运动: 关键在于DIV的边界检测,进而改变运动方向,即可实现碰撞反弹效果. <!DOCTYPE html> <html lang="en& ...

  7. Oracle中修改sysman和dbsnmp密码正确流程

    1.停止dbconsole $ emctl stop dbconsole 查看状态,确认dbconsole已经停止 $ emctl status dbconsole   2.修改sysman用户和db ...

  8. eclipse异常关闭,无法启动tomcat解决办法

    如果eclipse异常关闭,会出现以下 此时需要关闭javaw.exe即可,重新启动tomcat了. 关闭javaw.exe需要打开任务关闭器,选择详细信息,然后结束javaw.exe即可

  9. 【bzoj 4675】 点对游戏

    题目 发现一个人如果最终拿走了\(k\)个点,那么这个人的答案就是 \[\frac{\binom{n-2}{k-2}\sum_{i=1}^{n}\sum_{j=1}^{n}[dis(i,j)\in M ...

  10. 分布式唯一ID的几种生成方案

    前言 在互联网的业务系统中,涉及到各种各样的ID,如在支付系统中就会有支付ID.退款ID等.那一般生成ID都有哪些解决方案呢?特别是在复杂的分布式系统业务场景中,我们应该采用哪种适合自己的解决方案是十 ...