tsinsen A1393. Palisection (回文树)
来源:互联网 发布:远景论坛 知乎 编辑:程序博客网 时间:2024/06/06 07:14
A1393. Palisection
时间限制:2.0s 内存限制:256.0MB
总提交次数:392 AC次数:143 平均分:59.22
将本题分享到:
查看未格式化的试题 提交 试题讨论
试题来源
CODEFORCES 17E
问题描述
给你一个长度 n (1 ≤ n ≤ 2·106) 的只由小写字母组成的字符串s。
我们考虑s的所有连续且回文的子串集合P。位置不同但内容相同的两个串算作不同。
问从P中选出两个串且他们在s中有公共位置的方法数有几个?
我们考虑s的所有连续且回文的子串集合P。位置不同但内容相同的两个串算作不同。
问从P中选出两个串且他们在s中有公共位置的方法数有几个?
输入格式
第一行一个整数n
第二行字符串s
第二行字符串s
输出格式
一行答案,输出结果对51123987取余。
样例输入
4
babb
babb
样例输出
6
数据规模和约定
10%的数据 n<=5
15%的数据 n<=100
25%的数据 n<=1000
50%的数据 n<= 2·106
15%的数据 n<=100
25%的数据 n<=1000
50%的数据 n<= 2·106
反着插一次,计算后缀和,再正着插一次,计算没有重复位置的字符串对,然后用总的减掉就好了
/*======================================================# Author: whai## Last modified: 2015-10-05 17:03## Filename: tsinsen_A1393.cpp======================================================*/#include <iostream>#include <cstdio>#include <vector>#include <algorithm>#include <cstring>#include <cmath>#include <set>#include <map>using namespace std;#define LL long long#define PB push_back#define P pair<int, int>#define X first#define Y secondconst int N = 2 * 1e6 + 5;const int M = 26;const int MOD = 51123987;struct PalTree {int nxt[N][M]; //表示编号为i的节点表示的回文串在两边添加字符c以后变成的回文串的编号int fail[N]; //表示节点i失配以后跳转不等于自身的节点i表示的回文串的最长后缀回文串int cnt[N]; //表示节点i表示的本质不同的串的个数(建树时求出的不是完全的,最后count()函数跑一遍以后才是正确的)int num[N]; //表示以节点i表示的最长回文串的最右端点为回文串结尾的回文串个数int len[N]; //表示编号为i的节点表示的回文串的长度(一个节点表示一个回文串)int S[N]; //表示第i次添加的字符(一开始设S[0] = -1(可以是任意一个在串S中不会出现的字符))int last; //指向新添加一个字母后所形成的最长回文串表示的节点int n; //表示添加的字符个数int p; //表示添加的节点个数int new_node(int x) {memset(nxt[p], 0, sizeof(nxt[p]));cnt[p] = 0;num[p] = 0;len[p] = x;return p++;}void init() {p = 0;new_node(0);new_node(-1);last = 0;n = 0;S[0] = -1;fail[0] = 1;}int get_fail(int x) {while(S[n - len[x] - 1] != S[n]) x = fail[x];return x;}int add(int x) {x -= 'a';S[++n] = x;int cur = get_fail(last);if(!nxt[cur][x]) {int now = new_node(len[cur] + 2);fail[now] = nxt[get_fail(fail[cur])][x];nxt[cur][x] = now;num[now] = num[fail[now]] + 1;}last = nxt[cur][x];++cnt[last];return num[last];}void count() {for(int i = p - 1; i >= 0; --i)cnt[fail[i]] += cnt[i];}LL pal_str_num() {LL ret = 0;for(int i = p - 1; i > 0; --i) {cnt[fail[i]] = (cnt[fail[i]] + cnt[i]) % MOD;ret = (ret + cnt[i]) % MOD;}return ret;}};PalTree pt;char str[N];int sum[N];void gao(int n) {LL ans = 0;pt.init();sum[n] = 0;for(int i = n - 1; i >= 0; --i) {sum[i] = (sum[i + 1] + pt.add(str[i])) % MOD;}pt.init();for(int i = 0; i < n; ++i) {ans = (ans + (LL)pt.add(str[i]) * sum[i + 1]) % MOD;}LL all = pt.pal_str_num();ans = (((LL)all * (all - 1) / 2 % MOD - ans) % MOD + MOD) % MOD;cout<<ans<<endl;}int main() {int n;while(scanf("%d", &n) != EOF) {scanf("%s", str);gao(n);}return 0;}
0 0
- tsinsen A1393. Palisection (回文树)
- Tsinsen 题目A1393. Palisection(回文树)
- 【Tsinsen】A1393. Palisection 【Palindromic Tree】
- Tsinsen A1393. Palisection 【Palindromic Tree】
- CodeForces 17E Palisection(回文树)
- CodeForces 17E Palisection (回文树)
- Codeforces Beta Round #17 E. Palisection(回文树)
- 回文树 (tsinsen A1280. 最长双回文串)
- Tsinsen A1121 回文数
- 【回文串】Codeforces 17E Palisection
- Codeforces 17E Palisection 回文自动机+邻接表
- 【Tsinsen】A1280. 最长双回文串 【Palindromic Tree】
- Tsinsen 清橙 A1006. 特殊的数字2 (回文数)
- Tsinsen 清橙 A1007. 特殊的数字3 (回文数)
- 【Tsinsen】A1513. mex 线段树
- codeforces17E Palisection
- Codeforces17E-Palisection
- Tsinsen A1486. 树(树分治+字典树)
- Writing Fast Matlab code 2
- SQL with as 的用法 以及递归函数的写法
- ViewPager——之——PagerAdapter
- SQL Server的 排序规则(collation)冲突和解决方案
- [BZOJ1628]=[BZOJ1683][Usaco2007 Demo]City skyline
- tsinsen A1393. Palisection (回文树)
- MFC ODBC(一)
- iOS编程------自定义UITableViewCell / cell自适应高度
- [Python进阶-5]类的特殊方法
- 电话短信和邮件
- Codeforces Round #323 (Div. 2)A. Asphalting Roads
- 黑马程序员—Arrays工具类,数组的高级操作,基本数据类型包装类
- hdu5122 K.Bro Sorting
- 欢迎使用CSDN-markdown编辑器