题目链接

传送门

题意

给你一个串串,问你有多少对回文串相交。

思路

由于正着做不太好算答案,那么我们考虑用总的回文对数减去不相交的回文对数。

而不相交的回文对数可以通过计算以\(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+回文树)的更多相关文章

  1. Codeforces 932G Palindrome Partition - 回文树 - 动态规划

    题目传送门 通往???的传送点 通往神秘地带的传送点 通往未知地带的传送点 题目大意 给定一个串$s$,要求将$s$划分为$t_{1}t_{2}\cdots t_{k}$,其中$2\mid k$,且$ ...

  2. 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 ...

  3. Codeforces Beta Round #19D(Points)线段树

    D. Points time limit per test 2 seconds memory limit per test 256 megabytes input standard input out ...

  4. CodeForces 17E Palisection(回文树)

    E. Palisection time limit per test 2 seconds memory limit per test 128 megabytes input standard inpu ...

  5. 【CF17E】Palisection(回文树)

    [CF17E]Palisection(回文树) 题面 洛谷 题解 题意: 求有重叠部分的回文子串对的数量 所谓正难则反 求出所有不重叠的即可 求出以一个位置结束的回文串的数量 和以一个位置为开始的回文 ...

  6. CF17E Palisection(manacher/回文树)

    CF17E Palisection(manacher/回文树) Luogu 题解时间 直接正难则反改成求不相交的对数. manacher求出半径之后就可以差分搞出以某个位置为开头/结尾的回文串个数. ...

  7. Codeforces.GYM100548G.The Problem to Slow Down You(回文树)

    题目链接 \(Description\) 给定两个串\(S,T\),求两个串有多少对相同回文子串. \(|S|,|T|\leq 2\times 10^5\). \(Solution\) 好菜啊QAQ ...

  8. CF17E Palisection(回文树)

    题意翻译 给定一个长度为n的小写字母串.问你有多少对相交的回文子 串(包含也算相交) . 输入格式 第一行是字符串长度n(1<=n<=2*10^6),第二行字符串 输出格式 相交的回文子串 ...

  9. Palindrome Partition CodeForces - 932G 回文树+DP+(回文后缀的等差性质)

    题意: 给出一个长度为偶数的字符串S,要求把S分成k部分,其中k为任意偶数,设为a[1..k],且满足对于任意的i,有a[i]=a[k-i+1].问划分的方案数. n<=1000000 题解: ...

随机推荐

  1. 解决myeclipse2017 properties中文被Unicode编码

    输入:http://propedit.sourceforge.jp/eclipse/updates/ 在线安装插件解决.

  2. vim常用命令整理

    #创建文件 vim test.txt vi test.txt touch test.txt #在vim中要想退出,先按[esc],再输入如下命令 [:wq]保存并退出 [:q]退出,未修改 [:q!] ...

  3. mybatis:updatebyexample与updateByExampleSelective

    MyBatis,通常逆向工程工具生成接口和xml映射文件用于简单的单表操作. 有两个方法: updateByExample 和 updateByExampleSelective  ,作用是对数据库进行 ...

  4. [转帖]什么是IOC(控制反转)、DI(依赖注入)

    什么是IOC(控制反转).DI(依赖注入) 2018-08-22 21:29:13 Ming339456 阅读数 20642   原文地址(摘要了部分内容):https://blog.csdn.net ...

  5. Sitecore 9 为什么数据驱动的组织选择它

    Sitecore 9使用个性化和机器学习来帮助客户提高数字营销对数字投资的回报 Sitecore 9比以往任何时候都更加智能.主要功能包括: 数据集中化 向后兼容性 简单的迁移 该平台简化了营销人员和 ...

  6. 【C学习笔记】一

    一.运算符优先级 逻辑非>算术运算符>关系运算符>逻辑运算符>赋值运算符>逗号运算符 逻辑运算符>条件运算符>赋值运算符 对于if的执行语句,如果是一条语句那 ...

  7. 用shell脚本批量进行xss跨站攻击请求

    由于执行的xss攻击请求他多了,初步估计要执行83次,而且还要执行3篇,如果手工一个一个去执行,说出去,我还配叫自动化大师吗: 有鉴于此,边打算自己编写一个脚本进行批量执行: 而短脚本的编写,非she ...

  8. python 笔记——生成器和迭代器

    #-*- coding:utf-8 -*- a=[1,2,3,4] for i,j in enumerate(a): print i,j '''只有ij时,''' a=[1,2,3,4] for i ...

  9. HTTP协议随笔

    代理 代理就是处在客户端和服务端之间的服务器.客户端例如浏览器发送GET请求时,代理服务器接收该请求,并转发该请求至服务所在的服务器.服务器回复的数据和资源在第一时间经过代理服务器,才能回传到浏览器, ...

  10. VSCode 命令

    淘宝 NPM 镜像     https://npm.taobao.org/ Ctrl+~   显示终端 npm start    启动项目 cnpm install   安装模块