题意:

定义一个串为\(super\)回文串为:

\(\bullet\) 串s为主串str的一个子串,即\(s = str_lstr_{l + 1} \cdots str_r\)

\(\bullet\) 串s为回文串

\(\bullet\) 串\(str_lstr_{l + 1}...str_{\llcorner (l + r) / 2 \lrcorner}\)也是回文串

问长度为1、2、3 \(\cdots n\)的\(super\)回文串分别出现了几次

思路:

回文树建一下,然后每次新建一个节点的时候用hash快速判断一下是不是\(super\)回文串,然后回文树统计一下个数。

代码:

#include<map>
#include<set>
#include<cmath>
#include<cstdio>
#include<stack>
#include<ctime>
#include<vector>
#include<queue>
#include<cstring>
#include<string>
#include<sstream>
#include<iostream>
#include<algorithm>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int maxn = 3e5 + 5;
const int INF = 0x3f3f3f3f;
const ull seed = 131;
const ll MOD = 1e9 + 7;
using namespace std;
ull ha[maxn], fac[maxn];
int ans[maxn];
ull getstring(int l, int r){
return ha[r] - ha[l - 1] * fac[r - l + 1];
}
struct PAM{
int nex[maxn][26]; //指向的一个字符的节点
int fail[maxn]; //失配节点
int len[maxn]; //当前节点回文长度
int str[maxn]; //当前添加的字符串
int cnt[maxn]; //节点出现次数
int last;
int tot; //PAM中节点数
int N; //添加的串的个数 int satisfy[maxn]; int newnode(int L){
for(int i = 0; i < 26; i++) nex[tot][i] = 0;
len[tot] = L;
cnt[tot] = 0;
return tot++;
} void init(){
tot = 0;
newnode(0);
newnode(-1);
last = 0;
N = 0;
str[0] = -1;
fail[0] = 1;
} int getfail(int x){
while(str[N - len[x] - 1] != str[N]) x = fail[x];
return x;
} void add(char ss){
int c = ss - 'a';
str[++N] = c;
int cur = getfail(last);
if(!nex[cur][c]){
int now = newnode(len[cur] + 2);
fail[now] = nex[getfail(fail[cur])][c];
nex[cur][c] = now;
int need = (len[now] + 1) / 2;
if(len[now] == 1 || getstring(N - len[now] + 1, N - len[now] + need) == getstring(N - need + 1, N)) satisfy[now] = 1;
else satisfy[now] = 0;
}
last = nex[cur][c];
cnt[last]++;
} void count(){
for(int i = tot - 1; i >= 0; i--){
cnt[fail[i]] += cnt[i];
if(satisfy[i]) ans[len[i]] += cnt[i];
}
} }pa;
char s[maxn];
int main(){
fac[0] = 1;
for(int i = 1; i < maxn; i++) fac[i] = fac[i - 1] * seed;
while(~scanf("%s", s + 1)){
pa.init();
int len = strlen(s + 1);
ha[0] = 1;
for(int i = 1; i <= len; i++){
ha[i] = ha[i - 1] * seed + s[i];
}
for(int i = 1; i <= len; i++) ans[i] = 0;
for(int i = 1; i <= len; i++){
pa.add(s[i]);
}
pa.count();
for(int i = 1; i <= len; i++){
if(i != 1) printf(" ");
printf("%d", ans[i]);
}
puts("");
}
return 0;
}

杭电多校HDU 6599 I Love Palindrome String (回文树)题解的更多相关文章

  1. HDU 6599 I Love Palindrome String (回文树+hash)

    题意 找如下子串的个数: (l,r)是回文串,并且(l,(l+r)/2)也是回文串 思路 本来写了个回文树+dfs+hash,由于用了map所以T了 后来发现既然该子串和该子串的前半部分都是回文串,所 ...

  2. 杭电多校HDU 6579 Operation (线性基 区间最大)题解

    题意: 强制在线,求\(LR\)区间最大子集异或和 思路: 求线性基的时候,记录一个\(pos[i]\)表示某个\(d[i]\)是在某个位置更新进入的.如果插入时\(d[i]\)的\(pos[i]\) ...

  3. HDU 5157 Harry and magic string(回文树)

    Harry and magic string Time Limit: 2000/1000 MS (Java/Others)    Memory Limit: 32768/32768 K (Java/O ...

  4. HDU.5394.Trie in Tina Town(回文树)

    题目链接 \(Description\) 给定一棵\(Trie\).求\(Trie\)上所有回文串 长度乘以出现次数 的和.这里的回文串只能是从上到下的一条链. 节点数\(n\leq 2\times ...

  5. [2019杭电多校第二场][hdu6599]I Love Palindrome String(回文自动机&&hash)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6599 题目大意为求字符串S有多少个子串S[l,r]满足回文串的定义,并且S[l,(l+r)/2]也满足 ...

  6. 杭电多校HDU 6656 Kejin Player(概率DP)题解

    题意: 最低等级\(level\ 1\),已知在\(level\ i\)操作一次需花费\(a_i\),有概率\(p_i\)升级到\(level\ i+1\),有\(1 - p_i\)掉级到\(x_i( ...

  7. 杭电多校HDU 6601 Keen On Everything But Triangle(主席树)题解

    题意: 有\(n\)根长度不一的棍子,q次询问,求\([L,R]\)区间的棍子所能组成的周长最长的三角形.棍长\(\in [1, 1e9]\),n\(\in [1, 1e5]\). 思路: 由于不构成 ...

  8. 杭电多校HDU 6586 String(预处理 + 贪心)题解

    题意: 给你一个串,现需要你给出一个子序列,满足26个约束条件,\(len(A_i) >= L_i\) 且 \(len(A_i) <= R_i\), \(A_i\)为从a到z的26个字母. ...

  9. [2019杭电多校第三场][hdu6609]Find the answer(线段树)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6609 大致题意是求出每个位置i最小需要将几个位置j变为0(j<i),使得$\sum_{j=1}^ ...

随机推荐

  1. 阅读lodash源码之旅数组方法篇-compact和concat

    鲁迅说过:只有阅读过优秀库源码的人,才能配的上是真正的勇士. compact 创建一个新数组,包含原数组中所有的非假值元素.例如false, null,0, "", undefin ...

  2. LSM(Log Structured Merge Trees ) 笔记

    目录 一.大幅度制约存储介质吞吐量的原因 二.传统数据库的实现机制 三.LSM Tree的历史由来 四.提高写吞吐量的思路 4.1 一种方式是数据来后,直接顺序落盘 4.2 另一种方式,是保证落盘的数 ...

  3. uni-app开发经验分享一: 多页面传值的三种解决方法

    开发了一年的uni-app,在这里总结一些uni-app开发中的问题,提供几个解决方法,分享给大家: 问题描述:一个主页面,需要联通一到两个子页面,子页面传值到主页面,主页面更新 问题难点: 首先我们 ...

  4. LDAP 简介

    一.使用 Directory Services(目录服务)的目的 对于局域网内的一个用户来讲,工作等其它应用需要,我们必须凭帐号登录主机.用帐号收发E-mail,甚至为了管理需要公司还需要维护一个电子 ...

  5. (Oracle)关于blob转到目标库报ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值错误解决方案

    在数据抽取时,开发需要clob类型的数据,但是目标库类型是blob类型的,于是抽取的时候报错: ORA-01461: 仅能绑定要插入 LONG 列的 LONG 值错误 可能有以下几种原因: 可能有以下 ...

  6. 洛谷P2573

    Description \(n\) 个点,有各自的高度. \(m\) 条道路,有各自的长度,每条可连接两个点. 规定只能从高点走向低点,可以回到原来的某个位置走不同的道路. 求在行走道路尽量短的情况下 ...

  7. 某cms最新版前台RCE漏洞(无需任何权限)2020-03-15

    漏洞文件:application/common/controller/Base.php 中的 getAddonTemplate 方法: 错误的使用了public,导致我们可以直接外部访问. 然后使用了 ...

  8. jvm 总体梳理

    jvm 总体梳理 1.类的加载机制 1.1什么是类的加载 1.2类的生命周期 1.3类加载器 1.4类加载机制 2.jvm内存结构 JVM内存模型 2.1jvm内存结构 2.2对象分配规则 3.GC算 ...

  9. BigDecimal 用法详解

    BigDecimal简介 BigDecimal用法: BigDecimal的构造方法 BigDecimal常用方法描述 BigDecimal比较 BigDecimal总结 BigDecimal简介 J ...

  10. CyclicBarrier---可重用的循环栅栏

    很多文章只是提了下可重用,具体这个栅栏怎么可重用的,很多没有说明,这里会解开你的疑惑. CyclicBarrier是一个同步工具类,它允许一组线程互相等待,直到达到某个公共屏障点.与CountDown ...