I Love Palindrome String HDU - 6599 回文树+hash
题意:
输出每个长度下的回文串(这些回文串的左半边也需要是回文串)
题解:
直接套上回文树,然后每找到一个回文串就将他hash。
因为符合要求的回文串本身是回文串,左半边也是回文串,所以它左半边也右半边相同,
自己画个图很容易发现的
每次hash判断一下就好了
#include <set>
#include <map>
#include <stack>
#include <queue>
#include <cmath>
#include <ctime>
#include <cstdio>
#include <string>
#include <vector>
#include <cstring>
#include <iostream>
#include <algorithm>
#include <unordered_map> #define pi acos(-1.0)
#define eps 1e-9
#define fi first
#define se second
#define rtl rt<<1
#define rtr rt<<1|1
#define bug printf("******\n")
#define mem(a, b) memset(a,b,sizeof(a))
#define name2str(x) #x
#define fuck(x) cout<<#x" = "<<x<<endl
#define sfi(a) scanf("%d", &a)
#define sffi(a, b) scanf("%d %d", &a, &b)
#define sfffi(a, b, c) scanf("%d %d %d", &a, &b, &c)
#define sffffi(a, b, c, d) scanf("%d %d %d %d", &a, &b, &c, &d)
#define sfL(a) scanf("%lld", &a)
#define sffL(a, b) scanf("%lld %lld", &a, &b)
#define sfffL(a, b, c) scanf("%lld %lld %lld", &a, &b, &c)
#define sffffL(a, b, c, d) scanf("%lld %lld %lld %lld", &a, &b, &c, &d)
#define sfs(a) scanf("%s", a)
#define sffs(a, b) scanf("%s %s", a, b)
#define sfffs(a, b, c) scanf("%s %s %s", a, b, c)
#define sffffs(a, b, c, d) scanf("%s %s %s %s", a, b,c, d)
#define FIN freopen("../in.txt","r",stdin)
#define gcd(a, b) __gcd(a,b)
#define lowbit(x) x&-x
#define IO iOS::sync_with_stdio(false) using namespace std;
typedef long long LL;
typedef unsigned long long ULL;
const ULL seed = ;
const LL INFLL = 0x3f3f3f3f3f3f3f3fLL;
const int maxn = 1e6 + ;
const int maxm = 8e6 + ;
const int INF = 0x3f3f3f3f;
const int mod = 1e9 + ;
char s[maxn];
ULL p[maxn], HA[maxn];
int ans[maxn]; ULL get_HASH(int l, int r) {
return HA[r] - HA[l - ] * p[r - l + ];
} struct Palindrome_Automaton {
int len[maxn], next[maxn][], fail[maxn], cnt[maxn];
int num[maxn], str[maxn], sz, n, last;
int vis[maxn]; int newnode(int l) {
for (int i = ; i < ; ++i)next[sz][i] = ;
cnt[sz] = num[sz] = , len[sz] = l;
return sz++;
} void init() {
sz = n = last = ;
newnode();
newnode(-);
str[] = -;
fail[] = ;
mem(vis, );
} int get_fail(int x) {
while (str[n - len[x] - ] != str[n])x = fail[x];
return x;
} void add(int c, int pos) {
c -= 'a';
str[++n] = c;
int cur = get_fail(last);
if (!next[cur][c]) {
int now = newnode(len[cur] + );
fail[now] = next[get_fail(fail[cur])][c];
next[cur][c] = now;
num[now] = num[fail[now]] + ;
int temp = (len[now] + ) / ;
// fuck(n - len[now] + 1),fuck(n - len[now] + temp),fuck(n - temp),fuck(n);
if (len[now] == ||
get_HASH(n - len[now] + , n - len[now] + temp) == get_HASH(n - temp+, n))
vis[now] = ;
else vis[now] = ;
}
last = next[cur][c];
cnt[last]++;
} void count()//统计本质相同的回文串的出现次数
{
for (int i = sz - ; i >= ; --i) {
cnt[fail[i]] += cnt[i];
if (vis[i]) ans[len[i]] += cnt[i];
}
//逆序累加,保证每个点都会比它的父亲节点先算完,于是父亲节点能加到所有子孙
}
} pam; int main() {
// FIN;
p[] = ;
for (int i = ; i < maxn; ++i) p[i] = p[i - ] * seed;
while (~sfs(s + )) {
int n = strlen(s + );
pam.init();
for (int i = ; i <= n; ++i) {
HA[i] = HA[i - ] * seed + s[i];
pam.add(s[i], i);
ans[i] = ;
}
pam.count();
for (int i = ; i <= n; ++i) printf("%d%c", ans[i], (i == n ? '\n' : ' '));
}
return ;
}
I Love Palindrome String HDU - 6599 回文树+hash的更多相关文章
- HDU 6599 I Love Palindrome String (回文树+hash)
题意 找如下子串的个数: (l,r)是回文串,并且(l,(l+r)/2)也是回文串 思路 本来写了个回文树+dfs+hash,由于用了map所以T了 后来发现既然该子串和该子串的前半部分都是回文串,所 ...
- Palindrome Partition CodeForces - 932G 回文树+DP+(回文后缀的等差性质)
题意: 给出一个长度为偶数的字符串S,要求把S分成k部分,其中k为任意偶数,设为a[1..k],且满足对于任意的i,有a[i]=a[k-i+1].问划分的方案数. n<=1000000 题解: ...
- Interesting HDU - 5785 回文树
题意: 找出所有[i,j]为回文串[j+1,k]也为回文串的i*k乘积之和. 题解: 设sum1[i] 为正着插入,到 i 的所有回文串的起始位置的前缀和,sum2[i] 表示反正插入的前缀和 ans ...
- Gym - 101981M:(南京) Mediocre String Problem(回文树+exkmp)
#include<bits/stdc++.h> #define ll long long #define rep(i,a,b) for(int i=a;i<=b;i++) using ...
- 杭电多校HDU 6599 I Love Palindrome String (回文树)题解
题意: 定义一个串为\(super\)回文串为: \(\bullet\) 串s为主串str的一个子串,即\(s = str_lstr_{l + 1} \cdots str_r\) \(\bullet\ ...
- HDU 5157 Harry and magic string(回文树)
Harry and magic string Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/O ...
- HDU 5421 Victor and String(回文树)
Victor and String Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 524288/262144 K (Java/Othe ...
- Victor and String HDU - 5421 双向回文树
题意: 有n种操作,开始给你一个空串,给你4中操作 1 c 在字符串的首部添加字符c 2 c 在字符串的尾部添加字符c 3 询问字符中的本质不同的回文串的个数 4 询问字符串中回文串的个数 思路 ...
- HDU - 5421:Victor and String (回文树,支持首尾插入新字符)
Sample Input 6 1 a 1 b 2 a 2 c 3 4 8 1 a 2 a 2 a 1 a 3 1 b 3 4 Sample Output 4 5 4 5 11 题意:多组输入,开始字符 ...
随机推荐
- Java-Class-@I:javax.annotation.PostConstruct
ylbtech-Java-Class-@I:javax.annotation.PostConstruct 1.返回顶部 2.返回顶部 1.1. package com.ylbtech.api.pl ...
- Linux权限简析
- maven学习整理-基础知识
1.maven认识 maven是一种自动化的构建工具,它主要解决的问题有: ①项目中的划分规则:原先我们用package或文件夹的形式来划分不同模块,导致在一个项目中存在大量的文件夹和包代码显得庞大: ...
- git分布式版本控制系统权威指南学习笔记(四):git reset
文章目录 git reset目录树重写 git reset 重置 git reset目录树重写 git reset --soft 暂存区工作区不变 git reset --hard git reset ...
- C++——Struct 和 Union区别
1.在存储多个成员信息时,编译器会自动给struct第个成员分配存储空间,struct 可以存储多个成员信息,而Union每个成员会用同一个存储空间,只能存储最后一个成员的信息. 2.都是由多个不同的 ...
- Django框架(十)—— 多表操作:一对一、一对多、多对多的增删改,基于对象/双下划线的跨表查询、聚合查询、分组查询、F查询与Q查询
目录 多表操作:增删改,基于对象/双下划线的跨表查询.聚合查询.分组查询.F查询与Q查询 一.创建多表模型 二.一对多增删改表记录 1.一对多添加记录 2.一对多删除记录 3.一对多修改记录 三.一对 ...
- Pandas分类数据和顺序数据转换为标志变量
#导入pandas库 import pandas as pd #OneHotEncoder用来将数值型类别变量转换为0-1的标志性变量 #LabelEncoder用来将字符串型变量转换为数值型变量 f ...
- Airbub 弃用React Native
弃用 React Native ? 最近的技术圈尤为热闹,Google 发布了首个 Flutter 预览版.Vue.js 在 GitHub 上的 star 数量超过了 React.js,而如今全球著名 ...
- sanic连接mongo
方法一: #没有密码,就是没有用户和用户密码 settings={"MOTOR_URI":"mongodb://127.0.0.1:27017/zzy"} ap ...
- Swift与OC混合开发
一.Swift调用OC 1. 创建{targetName}-Bridging-Header.h头文件,在BuildSetting -> bridging 2. Swift文件调用的OC中的类的头 ...