Codeforces 17E Palisection - Manacher
好像很简单的样子。
考虑能不能直接求,感觉有点麻烦。因为要考虑右端点在当前回文子串内还有区间包含问题。
那么考虑补集转化。问题转化成,考虑当前的回文串,之前有多少个回文串与它不相交。
跑一遍Manacher。然后先差分再二阶前缀和求出以第$i$个位置为右端点的回文子串的个数。然后再求一次前缀和就可以了。
然后再扫一遍就做完了。
Code
/**
* Codeforces
* Problem#17E
* Accepted
* Time: 186ms
* Memory: 37200k
*/
#include <bits/stdc++.h>
using namespace std;
typedef bool boolean; const int N = 2e6 + , M = , inv2 = (M + ) >> ; int add(int a, int b) {
return ((a += b) >= M) ? (a - M) : (a);
} int sub(int a, int b){
return ((a -= b) < ) ? (a + M) : (a);
} int n, m;
char s[N], str[N << ];
int mxr[N << ];
int f[N]; inline void init() {
scanf("%d", &n);
scanf("%s", s + );
} void Manacher() {
int R = , cen = ;
str[] = '+';
for (int i = ; i <= n; i++) {
str[++m] = s[i];
if (i != n)
str[++m] = '#';
}
str[++m] = '-'; for (int i = ; i < m; i++) {
if (i < R)
mxr[i] = min(R - i, mxr[(cen << ) - i]);
while (str[i - mxr[i]] == str[i + mxr[i]])
mxr[i]++;
if (i + mxr[i] > R)
R = i + mxr[i], cen = i;
}
} inline void solve() {
Manacher();
for (int i = ; i < m; i++)
f[(i >> ) + ]++, f[((i + mxr[i]) >> ) + ]--;
for (int i = ; i <= n; i++)
f[i] = add(f[i], f[i - ]);
for (int i = ; i <= n; i++)
f[i] = add(f[i], f[i - ]);
int res = sub((f[n] * 1ll * f[n]) % M, f[n]) * 1ll * inv2 % M;
for (int i = ; i <= n; i++)
f[i] = add(f[i], f[i - ]);
f[] = , f[n + ] = ; for (int i = ; i <= n; i++) {
res = sub(res, sub(f[i - ], f[max(i - ((mxr[(i - ) << | ] + ) >> ) - , )]));
if (i < n)
res = sub(res, sub(f[i - ], f[max(i - (mxr[i << ] >> ) - , )]));
}
printf("%d\n", res);
} int main() {
init();
solve();
return ;
}
Codeforces 17E Palisection - Manacher的更多相关文章
- Codeforces 17E Palisection 【Manacher】
Codeforces 17E Palisection E. Palisection In an English class Nick had nothing to do at all, and rem ...
- CodeForces 17E Palisection(回文树)
E. Palisection time limit per test 2 seconds memory limit per test 128 megabytes input standard inpu ...
- [codeforces] 17E Palisection
原题 题目要求相交的回文串对数,这显然非常难,但是要有一种正难则反的心态,求不出来相交的,求出来不相交的不就好了! 对于每以位置i结尾的字符串,在他后面与他不相交的就是以这个位置为结尾的个数和以这个位 ...
- CF17E Palisection(manacher/回文树)
CF17E Palisection(manacher/回文树) Luogu 题解时间 直接正难则反改成求不相交的对数. manacher求出半径之后就可以差分搞出以某个位置为开头/结尾的回文串个数. ...
- 【Codeforces 17E】Palisection
Codeforces 17 E 题意:给一个串,求其中回文子串交叉的对数. 思路1:用哈希解决.首先求出每个点左右最长的回文串(要分奇数长度和偶数长度),然后记录经过每个点的回文串的个数,以及它们是在 ...
- CF17E Palisection manacher
题面:洛谷(带翻译) 题解: 直接求相交不太好求,所以考虑求不相交的回文串对数. 设ll[i]表示以i为开头的回文串个数,rr[i]表示结尾<=i的回文串个数. 然后不相交的回文串对数显然就是对 ...
- CF 17E Palisection 求相交回文串个数
In an English class Nick had nothing to do at all, and remembered about wonderful strings called pal ...
- Codeforces
Codeforces 7E #include <iostream> #include <cstring> #include <cstdio> #include &l ...
- 回文树练习 Part1
URAL - 1960 Palindromes and Super Abilities 回文树水题,每次插入时统计数量即可. #include<bits/stdc++.h> using ...
随机推荐
- python将字符串类型改成日期类型
将字符串类型的'2019-03-14'改成date类型,如下: import datetime b = datetime.date(*map(int,'2019-03-14'.split('-'))) ...
- pushd和popd
[原文地址] 其实,很早就知道pushd和popd在linux中可以用来方便地在多个目录之间切换.那时比较浮躁,感觉切换目录没必要这么复杂.在实际中,发现通过使用pushd和popd能够极大地提高 ...
- ArrayList 的代码
public class user { private String userName; //类的构造方法 public user (String userName ){ this.userName= ...
- 最短路(SPFA)
SPFA是Bellman-Ford算法的一种队列实现,减少了不必要的冗余计算. 主要思想是: 初始时将起点加入队列.每次从队列中取出一个元素,并对所有与它相邻的点进行修改,若某个相邻的点修改成功,则将 ...
- sql server中的charindex函数用法解析(在一段字符中搜索字符或者字符串-----返回expression1在expression2出现的位置;反之,返回0)
https://blog.csdn.net/xinghuo0007/article/details/70651358 知识点一:charindex()语法 CHARINDEX ( expression ...
- stm32专属于菜鸟的学习方法
1.首先我们先看看与STM32相关的文档 我们假定大家已经对STM32的书籍或者文档有一定的理解.如不理解,请立即阅读STM32的文档,以获取最基本的知识点. 如果你手上拥有ST官方主推的STM32神 ...
- [daily] fedora用过光盘做dnf repo
有时候上不了网,或者你在一个网络下行受限的鬼地方上班.可是你需要给你的server装一个包. 这个时候,不妨用一下安装盘吧! 如下: 与redhat下用yum的时候,是一样一样的. 步骤如下: 1,插 ...
- HTTP协议工作原理
HTTP简介 超文本传输协议(HTTP:Hypertext Transport Protocol)是万维网应用层的协议,它通过两个程序实现:一个是客户端程序(各种浏览器),另一个是服务器 ...
- nlp底层技术列举
其实目前除了之前博客写到的一些关于自然语言处理用到的知识点之外,很多其他nlp技术只是会用但是不了解原理,先整体分个类,之后再仔细分析吧. 上图是https://www.sohu.com/a/1386 ...
- 16.4-uC/OS-III同步 (任务信号量)
信号量和消息队列均是单独的内核对象,是独立于任务存在的. 任务信号量 仅发布给一个特定任务 .任务消息队列 可以发布给多个任务. 任务信号量伴随任务存在,只要创建了任务,其任务信号量就是该任务的一个数 ...