Palisection(Codeforces Beta Round #17E+回文树)
题目链接
题意
给你一个串串,问你有多少对回文串相交。
思路
由于正着做不太好算答案,那么我们考虑用总的回文对数减去不相交的回文对数。
而不相交的回文对数可以通过计算以\(i\)为右端点的回文串的个数\(\times\)以\(i+1,i+2\dots,n\)为左端点的回文串的个数计算得到。
以\(i\)为右端点的回文串的个数可以直接用回文树\(O(n)\)求出来,以\(i\)为左端点的回文串的个数反着求一遍即可。
不过要注意本题由于数据范围比较大,使用邻接矩阵会导致\(MLE\),因此需要使用邻接矩阵来代替。
代码实现如下
#include <set>
#include <map>
#include <deque>
#include <queue>
#include <stack>
#include <cmath>
#include <ctime>
#include <bitset>
#include <cstdio>
#include <string>
#include <vector>
#include <cassert>
#include <cstdlib>
#include <cstring>
#include <iostream>
#include <algorithm>
using namespace std;
typedef long long LL;
typedef pair<LL, LL> pLL;
typedef pair<LL, int> pLi;
typedef pair<int, LL> pil;;
typedef pair<int, int> pii;
typedef unsigned long long uLL;
#define lson rt<<1
#define rson rt<<1|1
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("in.txt","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0)
const double eps = 1e-8;
const int mod = 51123987;
const int maxn = 2e6 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
int n;
LL ans, tmp;
LL sum[maxn];
char s[maxn];
struct PAM {
//len数组表示以i为结尾的最长回文子串长度
//tot为结点数,lst为上一个字符加的位置
int N, totedge;
int str[maxn], head[maxn];
int fail[maxn], len[maxn], cnt[maxn], num[maxn], tot, lst;
void init() {
for(int i = 0; i <= n + 1; ++i) {
head[i] = -1;
cnt[i] = len[i] = fail[i] = num[i] = 0;
}
totedge = N = lst = 0; tot = 1; fail[0] = fail[1] = 1; len[1] = -1;
}
struct edge {
int v, w, next;
}ed[maxn];
void add(int u, int v, int w) {
ed[totedge].v = v;
ed[totedge].w = w;
ed[totedge].next = head[u];
head[u] = totedge++;
}
inline int fi(int u, int v) {
for(int i = head[u]; ~i; i = ed[i].next) {
if(ed[i].v == v) return ed[i].w;
}
return 0;
}
inline int add(int c) {
int p = lst;
str[++N] = c;
while(str[N - len[p] - 1] != str[N]) p = fail[p];
if(!(lst = fi(p, c))) {
int now = ++tot, k = fail[p];
len[now] = len[p] + 2;
while(str[N - len[k] - 1] != str[N]) k = fail[k];
fail[now] = fi(k, c);
add(p, c, now);
num[now] = num[fail[now]] + 1;
lst = now;
}
cnt[lst]++;
return num[lst];
}
inline void solve() {
for(int i = tot; i; i--) {
cnt[fail[i]] += cnt[i];
(tmp += cnt[i]) %= mod;
}
}
}pam;
int main() {
#ifndef ONLINE_JUDGE
FIN;
#endif
scanf("%d", &n);
scanf("%s", s + 1);
pam.init();
for(int i = n; i >= 1; --i) {
sum[i] = (sum[i+1] + pam.add(s[i] - 'a' + 1)) % mod;
}
pam.init();
for(int i = 1; i <= n; ++i) {
int cnt = pam.add(s[i] - 'a' + 1);
(ans += 1LL * cnt * sum[i+1] % mod) %= mod;
}
pam.solve();
printf("%lld\n", (((1LL * tmp * (tmp-1) / 2 % mod) - ans) % mod + mod) % mod);
return 0;
}
Palisection(Codeforces Beta Round #17E+回文树)的更多相关文章
- Codeforces 932G Palindrome Partition - 回文树 - 动态规划
题目传送门 通往???的传送点 通往神秘地带的传送点 通往未知地带的传送点 题目大意 给定一个串$s$,要求将$s$划分为$t_{1}t_{2}\cdots t_{k}$,其中$2\mid k$,且$ ...
- Codeforces 932G Palindrome Partition 回文树+DP
题意:给定一个串,把串分为偶数段 假设分为$s_1,s_2,s_3....s_k$ 求满足$ s_1=s_k,s_2=s_{ k-1 }... $的方案数模$10^9+7$ $|S|\leq 10^6 ...
- Codeforces Beta Round #19D(Points)线段树
D. Points time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...
- CodeForces 17E Palisection(回文树)
E. Palisection time limit per test 2 seconds memory limit per test 128 megabytes input standard inpu ...
- 【CF17E】Palisection(回文树)
[CF17E]Palisection(回文树) 题面 洛谷 题解 题意: 求有重叠部分的回文子串对的数量 所谓正难则反 求出所有不重叠的即可 求出以一个位置结束的回文串的数量 和以一个位置为开始的回文 ...
- CF17E Palisection(manacher/回文树)
CF17E Palisection(manacher/回文树) Luogu 题解时间 直接正难则反改成求不相交的对数. manacher求出半径之后就可以差分搞出以某个位置为开头/结尾的回文串个数. ...
- Codeforces.GYM100548G.The Problem to Slow Down You(回文树)
题目链接 \(Description\) 给定两个串\(S,T\),求两个串有多少对相同回文子串. \(|S|,|T|\leq 2\times 10^5\). \(Solution\) 好菜啊QAQ ...
- CF17E Palisection(回文树)
题意翻译 给定一个长度为n的小写字母串.问你有多少对相交的回文子 串(包含也算相交) . 输入格式 第一行是字符串长度n(1<=n<=2*10^6),第二行字符串 输出格式 相交的回文子串 ...
- Palindrome Partition CodeForces - 932G 回文树+DP+(回文后缀的等差性质)
题意: 给出一个长度为偶数的字符串S,要求把S分成k部分,其中k为任意偶数,设为a[1..k],且满足对于任意的i,有a[i]=a[k-i+1].问划分的方案数. n<=1000000 题解: ...
随机推荐
- [转]MySQL之——崩溃-修复损坏的innodb:innodb_force_recovery
原文 https://blog.csdn.net/l1028386804/article/details/77199194 1. mysql崩溃 --------------------------- ...
- Navicat连接mysql数据库2003-Can't connect to Mysql server on 'xxx' (10060 "Unknown error")
使用root账号连接MySQL 1,登录 mysql -u用户名 -p 回车后输入密码 2, use mysql 3,输入下面命令,显示root为localhost本地登 ...
- vim文本编辑器的使用
1.简介 vim是vi发展过来的一款文本编辑器,功能非常强大. 2.vim的工作模式 vim有三种工作模式,分别为命令模式.编辑模式.末行模式: 1)命令模式:打开文件之后,默认进入命令模式: 2)编 ...
- MySQL 索引小结
1.!=.not in 在primary key上使用 !=.not in,explain 的 type 是 range,非primary key是全表扫描(即非主键字段即使有索引也无法应用) 2.a ...
- Win10 系统直接在目录下打开cmd
每次用cmd命令,就要定位到当前文件夹,很麻烦 这里介绍一种直接定位到要操作的文件夹的方法: 操作步骤: (1)选择要cmd的文件夹,按住Shift键,鼠标右键快捷方式,先打开Powershell窗口 ...
- 微信企业微信调试JS神器vConsole
在js页面上放以下代码 <script src='https://cdn.bootcss.com/vConsole/3.3.2/vconsole.min.js'></script&g ...
- Svn CleanUp failed解决方案
在项目目录下找到wc.db文件,使用sqlite工具打开,清空main下的WC_LOCK和 WORK_QUEUE表即可.
- 【Mac+Android+uiautomatorviewer】之报错:Unexpected error while obtaining UI hierarchy java.lang.reflect.InvocationTargetException
安卓8.0以后uiautomatorviewer会报错,解决办法如下: 参考:<android 8.0 以后 uiautomator 无法直接使用的问题> 步骤一: 先执行命令:(注意:想 ...
- mysql密码中有特殊字符&在命令行下登录
在服务器上,通常为了快速登录数据库,我们会使用mysql -hhost -uusername -ppassword db的方式登录数据库,如果密码中没有特殊字符&,会直接进入数据库sql命令行 ...
- Ubuntu 18 Kubernetes集群的安装和部署 以及Helm的安装
首先说一下我的环境, 我是在windows 10 上面建了一个ubuntu18的虚拟机,同时由于某些原因 不受网络限制, 所以安装比较顺利. Install 1.安装并启用 Docker sudo ...