因为没有简化题意一直没去做,直到今天讲这道题才口胡出来

要求对称,很明显这样一个“子序列”的对称中心只可能有一个,那么先枚举这个对称中心。

然后我们需要判断两个位置是否相同。看上去好像很困难。

考虑设计哈希函数 \(f(x,y)\),使得 \(f(V_a,V_b)\neq 0\) 且 \(f(V_a,V_a)=f(V_b,V_b)=0\)。

首先等于 \(0\),那么一定有一个 \((x-y)\)。其次,注意到字符集只有 \(2\),为了方便,我们令 \(f(x,y)=-f(y,x)\)。那么就包含了 \((x-y)^2\)。

所以 \(f(x,y)=(V_x-V_y)^2=V_x^2+V_y^2-2V_xV_y\),这就够了。

我们需要计算的是 \(match[i]=\sum_{j=0}f(i-j,i+j)\),这有点像卷积。

拆开得到:

\[\sum_{j=0}(V_{i-j}^2+V_{i+j}^2)-2V_{i+j}V_{i-j}
\]

后面这玩意儿可以用前缀和搞定,前面这玩意儿做一个卷积就好啦。

这样做会算上连续的一段,使用 manacher 计算出来并且减掉就好啦。

复杂度 \(O(n\log n)\)。

#include<cstring>
#include<cstdio>
typedef unsigned ui;
const ui M=1e5+5,G=3,mod=998244353,MOD=1e9+7;
ui n,V[M],S[M],pw2[M],f[M<<2];ui ans;char s[M];
ui p[M<<1];char c[M<<1];
inline ui min(const ui&a,const ui&b){
return a>b?b:a;
}
inline ui pow(ui a,ui b=mod-2){
ui ans(1);for(;b;b>>=1,a=1ull*a*a%mod)if(b&1)ans=1ull*ans*a%mod;return ans;
}
inline ui Add(const ui&a,const ui&b){
return a+b>=mod?a+b-mod:a+b;
}
inline ui Del(const ui&a,const ui&b){
return b>a?a-b+mod:a-b;
}
inline void swap(ui&a,ui&b){
ui c=a;a=b;b=c;
}
inline void DFT(ui*f,const ui&n){
for(ui len=n>>1;len>=1;len>>=1){
const ui w1=pow(G,(mod-1>>1)/len);
for(ui k=0;k<n;k+=len<<1){
for(ui w(1),i=0;i<len;++i){
const ui x=f[i|k],y=f[i|k|len];
f[i|k]=Add(x,y);f[i|k|len]=1ull*w*Del(x,y)%mod;
w=1ull*w*w1%mod;
}
}
}
}
inline void IDFT(ui*f,const ui&n){
for(ui len=1;len<n;len<<=1){
const ui w1=pow(G,(mod-1>>1)/len);
for(ui k=0;k<n;k+=len<<1){
for(ui w(1),i=0;i<len;++i){
const ui x=f[i|k],y=1ull*w*f[i|k|len]%mod;
f[i|k]=Add(x,y);f[i|k|len]=Del(x,y);
w=1ull*w*w1%mod;
}
}
}
const ui inv=pow(n);
for(ui i=0;i<n;++i)f[i]=1ull*f[i]*inv%mod;
for(ui i=1;(i<<1)<n;++i)swap(f[i],f[n-i]);
}
inline ui manacher(char*s){
ui R(0),mid(0),ans(0);c[0]='^';c[1]='#';
for(ui i=1;i<=n;++i)c[i<<1]=s[i],c[i<<1|1]='#';
for(ui i=1;i<=(n<<1);++i){
p[i]=i<=R?min(p[(mid<<1)-i],p[mid]+mid-i):1;
while(c[i-p[i]]==c[i+p[i]])++p[i];
if(i+p[i]-1>R)mid=i,R=i+p[i]-1;
ans=(ans+(p[i]>>1))%MOD;
}
return ans;
}
signed main(){
scanf("%s",s+1);n=strlen(s+1);pw2[0]=1;
for(ui i=1;i<=n;++i){
V[i]=s[i]=='a'?1:2;pw2[i]=pw2[i-1]*2%MOD;
f[i]=V[i];S[i]=S[i-1]+V[i]*V[i];
}
ui len(1);
while(len<n+n+1)len<<=1;
DFT(f,len);
for(ui i=0;i<len;++i)f[i]=1ull*f[i]*f[i]%mod;
IDFT(f,len);
for(ui i=1;i<=n;++i){
ui len=min(n-i,i-1);
ans=(ans+pw2[len+1-((S[i+len]-S[i-len-1])-f[i<<1])]-1)%MOD;
if(len!=n-i)++len;
ans=(ans+pw2[len-((S[i+len]-S[i-len])-f[i<<1|1])]-1)%MOD;
}
printf("%u",(MOD+ans-manacher(s))%MOD);
}

LGP4199题解的更多相关文章

  1. 2016 华南师大ACM校赛 SCNUCPC 非官方题解

    我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ...

  2. noip2016十连测题解

    以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ...

  3. BZOJ-2561-最小生成树 题解(最小割)

    2561: 最小生成树(题解) Time Limit: 10 Sec  Memory Limit: 128 MBSubmit: 1628  Solved: 786 传送门:http://www.lyd ...

  4. Codeforces Round #353 (Div. 2) ABCDE 题解 python

    Problems     # Name     A Infinite Sequence standard input/output 1 s, 256 MB    x3509 B Restoring P ...

  5. 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解

    题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ...

  6. 2016ACM青岛区域赛题解

    A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/65536 K (Jav ...

  7. poj1399 hoj1037 Direct Visibility 题解 (宽搜)

    http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ...

  8. 网络流n题 题解

    学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ...

  9. CF100965C题解..

    求方程 \[ \begin{array}\\ \sum_{i=1}^n x_i & \equiv & a_1 \pmod{p} \\ \sum_{i=1}^n x_i^2 & ...

随机推荐

  1. iOS 模糊、精确搜索匹配功能方法总结 By HL

    字符串搜索主要用于UITableView的搜索功能的筛选,过滤,查询 下面是一些流行的搜索查询方法 一.遍历搜索 for循环 根据要求:精确搜索(判读字符串相等)   模糊搜索(字符串包含) 相关知识 ...

  2. Java多线程之读写锁机制

    Java多线程中有很多的锁机制,他们都有各自的应用场景,例如今天我说的这种锁机制:读写锁 读写锁,见名知意,主要可以进行两种操作,读和写操作,他们之间结合使用起来又是各不相同的.比如多个线程之间可以同 ...

  3. Scala概述及环境配置

    一.概述 1.1 为什么要学Scala? Spark是新一代的内存级大数据的计算框架,是大数据学习的重要内容.随着Spark的兴起,同时也带动了Scala的学习,因为Spark就是Scala编写的.为 ...

  4. 关于一些基础的dp——硬币的那些事(dp的基本引入)

    1.最少硬币问题大体题意: 有n种硬币,面值分别是v1,v2......vn,数量无限,输入一个非负整数s,选用硬币使其和为s,要求输出最少的硬币组合. 我们可以这样分析: 定义一个名为Min[s]的 ...

  5. node Cheerio 获取script脚本里的数据

    const cheerio = require('cheerio'); const $ = cheerio.load(html); // your html//如果有多少script脚本标签使用循环来 ...

  6. Solution -「洛谷 P6021」洪水

    \(\mathcal{Description}\)   Link.   给定一棵 \(n\) 个点的带点权树,删除 \(u\) 点的代价是该点点权 \(a_u\).\(m\) 次操作: 修改单点点权. ...

  7. 我们一起来学grep

    文章目录 grep 介绍 grep 命令格式 grep 命令选项 grep 实例 查找指定进程 查找指定进程个数 从文件中读取关键词进行搜索 从多个文件中查找关键字 输出以u开头的行 输出非u开头的行 ...

  8. 多表查询思路、navicat可视化软件、python操作MySQL、SQL注入问题以及其他补充知识

    昨日内容回顾 外键字段 # 就是用来建立表与表之间的关系的字段 表关系判断 # 一对一 # 一对多 # 多对多 """通过换位思考判断""" ...

  9. vue methods中的函数调用时带括号与不带括号的区别

    @click='getList(id)',但是为什么有时候明明没有传参的需要,却要加上()呢? 百思不得其解,于是去查阅了相关的资料,意思就是,当不加括号直接调用这个函数是可以直接获取到这个事件对象的 ...

  10. nginx域名转发

    场景1:因服务器限制,所以只对外开放了一个端口,但是需要请求不同的外网环境,所以在中转服务器上用nginx做了一次转发 实现: server { listen 8051; server_name lo ...