BZOJ 3160 万径人踪灭 解题报告
这个题感觉很神呀。将 FFT 和 Manacher 有机结合在了一起。
首先我们不管那个 “不能连续” 的条件,那么我们就可以求出有多少对字母关于某一条直线对称,然后记 $T_i$ 为关于直线 $i$ 对称的字母对的数量,那么答案(暂记为 $Ans$)就会是:
$$Ans = \sum 2^{T_i}-1$$
在不管那个 “不能连续” 的条件的时候,这个应该是显然的。
怎么算的话,我们弄两次。分别把 $a$ 和 $b$ 当做 $1$,另一个当做 $0$,然后就可以得到一个多项式,将这个多项式平方一下就可以得到所有的 $T_i$ 了,具体用 FFT 实现。
那么我们来管一管这个条件。
我们就可以用 Manacher 求出每一条直线的最长回文半径,然后记 $R_i$ 为直线 $i$ 的最长回文半径,那么实际上的总答案就会是:
$$Ans - \sum R_i$$
然后就做完啦。令 $n$ 为字符串的长度:
时间复杂度 $O(n\log n)$,空间复杂度 $O(n)$。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
typedef long long LL;
#define N 262144 + 5
#define _Mod 1000000007
#define Mod 998244353
#define g 3 int n, len, Inv_len, d, ans, e[][N], Rev[N], A[N], T[N], R[N];
char s[N]; inline int Inc(int u, int v, int p)
{
return u + v - (u + v >= p ? p : );
} inline int power(int u, int v, int p)
{
int res = ;
for (; v; v >>= )
{
if (v & ) res = (LL) res * u % p;
u = (LL) u * u % p;
}
return res;
} inline void FFT_Prepare()
{
for (len = n << ; len != (len & -len); len += (len & -len)) ;
for (int i = len; i > ; i >>= ) d ++;
int w = power(g, (Mod - ) / len, Mod);
int Inv_w = power(w, Mod - , Mod);
Inv_len = power(len, Mod - , Mod);
for (int i = ; i < len; i ++)
{
e[][i] = !i ? : (LL) e[][i - ] * w % Mod;
e[][i] = !i ? : (LL) e[][i - ] * Inv_w % Mod;
for (int j = ; j < d; j ++)
if ((i >> j) & ) Rev[i] += << (d - j - );
}
} inline void FFT(int *p, int op)
{
for (int i = ; i < len; i ++)
if (Rev[i] > i) swap(p[Rev[i]], p[i]);
for (int k = , s = ; k < len; k <<= , s ++)
for (int i = ; i < len; i ++)
{
if (i & k) continue ;
int t = (i & (k - )) << (d - s);
int u = Inc(p[i], (LL) p[i + k] * e[op][t] % Mod, Mod);
int v = Inc(p[i], (LL) (Mod - p[i + k]) * e[op][t] % Mod, Mod);
p[i] = u, p[i + k] = v;
}
} inline void FFT_Work(char key)
{
memset(A, , sizeof(A));
for (int i = ; i < n; i ++)
A[i] = (s[i] == key);
FFT(A, );
for (int i = ; i < len; i ++)
A[i] = (LL) A[i] * A[i] % Mod;
FFT(A, );
for (int i = ; i < len; i ++)
T[i] = Inc(T[i], (LL) A[i] * Inv_len % Mod, Mod);
} inline void Manacher()
{
for (int i = (n << ); i >= ; i --)
s[i] = i & ? s[i >> ] : 'c';
int mx = -, id;
for (int i = ; i <= (n << ); i ++)
{
if (mx > i)
R[i] = min(R[id * - i], mx - i);
else R[i] = ;
for (; i + R[i] <= (n << ) && i - R[i] >= && s[i + R[i]] == s[i - R[i]]; R[i] ++) ;
if (i + R[i] > mx)
mx = i + R[i], id = i;
}
} int main()
{
scanf("%s", s);
n = strlen(s);
FFT_Prepare();
for (char ch = 'a'; ch <= 'b'; ch ++)
FFT_Work(ch);
for (int i = ; i < len; i ++)
{
T[i] = (T[i] + ) >> ;
ans = Inc(ans, power(, T[i], _Mod) - , _Mod);
}
Manacher();
for (int i = ; i <= (n << ); i ++)
ans = Inc(ans, _Mod - R[i] / , _Mod);
printf("%d\n", ans); return ;
}
3160_Gromah
BZOJ 3160 万径人踪灭 解题报告的更多相关文章
- BZOJ 3160: 万径人踪灭 FFT+快速幂+manacher
BZOJ 3160: 万径人踪灭 题目传送门 [题目大意] 给定一个长度为n的01串,求有多少个回文子序列? 回文子序列是指从原串中找出任意个,使得构成一个回文串,并且位置也是沿某一对称轴对称. 假如 ...
- 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: 万径人踪灭
Description 一个ab串,问有多少回文子序列,字母和位置都对称,并且不连续. Sol FFT+Manacher. 不连续只需要减去连续的就可以了,连续的可以直接Manacher算出来. 其他 ...
- BZOJ 2959: 长跑 解题报告
2959: 长跑 Description 某校开展了同学们喜闻乐见的阳光长跑活动.为了能"为祖国健康工作五十年",同学们纷纷离开寝室,离开教室,离开实验室,到操场参加3000米长跑 ...
- bzoj 3160 万径人踪灭——FFT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3160 似乎理解加深了. 用卷积算相同的位置:先把 a 赋成1. b 赋成0,卷积一遍:再把 ...
- bzoj 3160 万径人踪灭 FFT
万径人踪灭 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1936 Solved: 1076[Submit][Status][Discuss] De ...
- bzoj 3160 万径人踪灭 —— FFT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=3160 求出关于一个位置有多少对对称字母,如果 i 位置有 f[i] 对,对答案的贡献是 2^ ...
- BZOJ 4238 电压 解题报告
BZOJ 4238 电压 考虑一条边成为答案以后,删去Ta后剩下的图是一个或很多个二分图,即没有奇环 则一条边可以成为答案,当且仅当自己在所有奇环的交上且不在偶环上. 考虑建出dfs树,那么返祖边一定 ...
随机推荐
- Nginx - Core Module Directives
The following is the list of directives made available by the Core module. Most of these directives ...
- C#算法基础之递归排序
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.T ...
- 利用ADO方式连接SQLServer2008出现的问题
在利用ADO方式连接SQLServer2008的过程中遇到了很多问题,在网上也没有找到许多有利的信息,花了两天时间,终于把所有问题都搞定了.在这里和大家分享一下经验,希望后来者能少走弯路. 很多教程说 ...
- CSS 文字溢出时的自动隐藏
http://www.111cn.net/cssdiv/css/34050.htm 语法:overflow : visible | auto | hidden | scroll visible::不剪 ...
- wampserver安装后 mysql 所有数据库丢失的解决方案
事情起源: 晚上十点客户紧急来电,说是网站全部瘫痪.同事登陆数据库一看,Mysql Workbench Database下一片空白.当时我们都傻了. 发现原因: 服务器环境是windows serve ...
- javascript笔记——JavaScript经典实例
转载自百度文库 http://wenku.baidu.com/view/9a703522bcd126fff7050bfa.html 1. oncontextmenu="window.even ...
- Eclipse JavaEE设置内置浏览器和外部浏览器
Eclipse JavaEE设置内置浏览器和外部浏览器 我们在使用Java EE版本的Eclipse开发Java Web程序时,Eclipse会有一个默认的内置浏览器查看网页的效果,如下图 但是内置浏 ...
- Contest1065 - 第四届“图灵杯”NEUQ-ACM程序设计竞赛(个人赛)B一个简单的问题
题目描述 这是一个三层的字母塔. 如何输出一个任意层数的字母塔呢? 输入 一个数字n(1<=n<=26),表示字母塔的层数 注意 此题多组输入 输出 n层的字母塔 样例输入 3 4 样例 ...
- 九度 1420 Jobdu MM分水果 -- 动态规划、深度优先搜索
题目地址:http://ac.jobdu.com/problem.php?pid=1420 题目描述: Jobdu团队有俩PPMM,这俩MM干啥都想一样.一天,富强公司给团队赞助了一批水果,胡老板就把 ...
- Winform 下拉框绑定问题
在Winform中下拉框绑定的时候只能读到text属性值,Id的值不管怎么搞都读取不到,所以就百度找到了一种方式: public void CmdBind() { var data = _logic. ...