Palindrome Mouse(2019年牛客多校第六场C题+回文树+树状数组)
题目链接
题意
问\(s\)串中所有本质不同的回文子串中有多少对回文子串满足\(a\)是\(b\)的子串。
思路
参考代码:传送门
本质不同的回文子串肯定是要用回文树的啦~
在建好回文树后分别对根结点为\(0,1\)的子树进行\(dfs\),处理出以每个结点为根结点的子树的大小\(sz\)(也就是说有多少个回文子串以其为中心)和其\(dfs\)序,回文子串包含除了作为其他回文子串的中心被包含外,还可以不作为中心被包含,而这一部分则需要靠回文树的\(fail\)数组来进行处理。
我们先用\(vector\)存下有多少个结点的\(fail\)数组指向\(i\),然后把这些结点按照其对应的回文串长度进行排序,用树状数组来防止去重,加入这个结点对应的\(dfs\)序没被覆盖,那么就加上这个结点的\(sz\),否则就不加。此处举个例子帮助理解:\(cac,cedcacdec\)的\(fail\)数组都指向了\(c\),但是\(cedcacdec\)是\(cac\)子树中的结点,我们在加\(cac\)的时候已经把\(cedcacdec\)的贡献计算过了,如果再加一次就会重复,因此如果某个结点的\(dfs\)序被前面长度短的结点包含过,那么就不用加进答案中。
代码
#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),L,mid
#define rson (rt<<1|1),mid + 1,R
#define lowbit(x) x&(-x)
#define name2str(name) (#name)
#define bug printf("*********\n")
#define debug(x) cout<<#x"=["<<x<<"]" <<endl
#define FIN freopen("/home/dillonh/CLionProjects/Dillonh/in.txt","r",stdin)
#define IO ios::sync_with_stdio(false),cin.tie(0)
const double eps = 1e-8;
const int mod = 1000000007;
const int maxn = 100000 + 7;
const double pi = acos(-1);
const int inf = 0x3f3f3f3f;
const LL INF = 0x3f3f3f3f3f3f3f3fLL;
int _, n, cnt;
char s[maxn];
vector<int> vec[maxn];
int sz[maxn], ls[maxn], rs[maxn], vis[maxn];
struct PAM {
//len数组表示以i为结尾的最长回文子串长度
//tot为结点数,lst为上一个字符加的位置
int N;
int str[maxn];
int ch[maxn][30], fail[maxn], len[maxn], cnt[maxn], tot, lst;
void init() {
for(int i = 0; i <= n + 1; ++i) {
cnt[i] = len[i] = fail[i] = 0;
for(int j = 0; j <= 26; ++j) ch[i][j] = 0;
}
N = lst = 0; tot = 1; fail[0] = fail[1] = 1; len[1] = -1;
}
inline void add(int c) {
int p = lst;
str[++N] = c;
while(str[N - len[p] - 1] != str[N]) p = fail[p];
if(!ch[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] = ch[k][c]; ch[p][c] = now;
}
lst = ch[p][c]; cnt[lst]++;
}
inline void solve() {
for(int i = tot; i; i--) {
cnt[fail[i]] += cnt[i];
}
}
}pam;
int tree[maxn];
void add(int x, int val) {
while(x < maxn) {
tree[x] += val;
x += lowbit(x);
}
}
int query(int x) {
int ans = 0;
while(x) {
ans += tree[x];
x -= lowbit(x);
}
return ans;
}
void dfs(int u) {
sz[u] = 1;
ls[u] = ++cnt;
for(int i = 1; i <= 26; ++i) {
if(pam.ch[u][i]) {
dfs(pam.ch[u][i]);
sz[u] += sz[pam.ch[u][i]];
}
}
rs[u] = cnt;
}
int main() {
#ifndef ONLINE_JUDGE
FIN;
#endif
scanf("%d", &_);
for(int __ = 1; __ <= _; ++__) {
scanf("%s", s + 1);
n = strlen(s + 1);
pam.init();
for(int i = 1; i <= n; ++i) pam.add(s[i] - 'a' + 1);
cnt = 0;
dfs(1);
dfs(0);
LL ans = 0;
for(int i = 2; i <= pam.tot; ++i) vec[i].clear();
for(int i = 2; i <= pam.tot; ++i) {
if(pam.fail[i] >= 2) vec[pam.fail[i]].emplace_back(i);
}
for(int i = 2; i <= pam.tot; ++i) {
vec[i].emplace_back(i);
sort(vec[i].begin(), vec[i].end(), [](int x, int y) {return pam.len[x] < pam.len[y];});
LL sum = 0;
for(int j = 0; j < (int)vec[i].size(); ++j) {
int u = vec[i][j];
if(query(ls[u]) == 0) {
sum += sz[u];
add(ls[u], 1);
add(rs[u] + 1, -1);
vis[j] = 1;
}
}
ans += sum - 1;
for(int j = 0; j < (int)vec[i].size(); ++j) {
if(!vis[j]) continue;
int u = vec[i][j];
add(ls[u], -1);
add(rs[u] + 1, 1);
vis[j] = 0;
}
}
printf("Case #%d: %lld\n", __, ans);
}
return 0;
}
Palindrome Mouse(2019年牛客多校第六场C题+回文树+树状数组)的更多相关文章
- 2019牛客多校第八场 F题 Flowers 计算几何+线段树
2019牛客多校第八场 F题 Flowers 先枚举出三角形内部的点D. 下面所说的旋转没有指明逆时针还是顺时针则是指逆时针旋转. 固定内部点的答案的获取 anti(A)anti(A)anti(A)或 ...
- Distance(2019年牛客多校第八场D题+CDQ+树状数组)
题目链接 传送门 思路 这个题在\(BZOJ\)上有个二维平面的版本(\(BZOJ2716\)天使玩偶),不过是权限题因此就不附带链接了,我也只是在算法进阶指南上看到过,那个题的写法是\(CDQ\), ...
- 2019年牛客多校第四场 B题xor(线段树+线性基交)
题目链接 传送门 题意 给你\(n\)个基底,求\([l,r]\)内的每个基底是否都能异或出\(x\). 思路 线性基交板子题,但是一直没看懂咋求,先偷一份咖啡鸡板子写篇博客吧~ 线性基交学习博客:传 ...
- generator 1(2019年牛客多校第五场B题+十进制矩阵快速幂)
目录 题目链接 思路 代码 题目链接 传送门 思路 十进制矩阵快速幂. 代码 #include <set> #include <map> #include <deque& ...
- Find the median(2019年牛客多校第七场E题+左闭右开线段树)
题目链接 传送门 题意 每次往集合里面添加一段连续区间的数,然后询问当前集合内的中位数. 思路 思路很好想,但是卡内存. 当时写的动态开点线段树没卡过去,赛后机房大佬用动态开点过了,\(tql\). ...
- Explorer(2019年牛客多校第八场E题+线段树+可撤销并查集)
题目链接 传送门 题意 给你一张无向图,每条边\(u_i,v_i\)的权值范围为\([L_i,R_i]\),要经过这条边的条件是你的容量要在\([L_i,R_i]\),现在问你你有多少种容量使得你可以 ...
- 2019年牛客多校第三场 F题Planting Trees(单调队列)
题目链接 传送门 题意 给你一个\(n\times n\)的矩形,要你求出一个面积最大的矩形使得这个矩形内的最大值减最小值小于等于\(M\). 思路 单调队列滚动窗口. 比赛的时候我的想法是先枚举长度 ...
- [题解]Shorten IPv6 Address-模拟(2019牛客多校第六场B题)
题目链接:https://ac.nowcoder.com/acm/contest/886/B 题意: 您将获得一个IPv6地址,该地址是128位二进制字符串.请根据以下规则确定其最短的表示: 以十六进 ...
- 2020牛客多校第八场K题
__int128(例题:2020牛客多校第八场K题) 题意: 有n道菜,第i道菜的利润为\(a_i\),且有\(b_i\)盘.你要按照下列要求给顾客上菜. 1.每位顾客至少有一道菜 2.给顾客上菜时, ...
随机推荐
- [LeetCode] 289. Game of Life 生命游戏
According to the Wikipedia's article: "The Game of Life, also known simply as Life, is a cellul ...
- Spring Boot 知识笔记(集成zookeeper)
一.本机搭建zookeeper伪集群 1.下载安装包,复制三份 2.每个安装包目录下面新建一个data文件夹,用于存放数据目录 3.安装包的conf目录下,修改zoo.cfg配置文件 # The nu ...
- idea插件篇之java内存分析工具(JProfiler)
前言在运行java的时候有时候想测试云运行时占用内存情况,这时候就需要使用测试工具查看了.在eclipse里面有 Eclipse Memory Analyzer tool(MAT)插件可以测试,而在i ...
- twig输出转义
twig输出转义--需求:传一个变量到 twig 中,需要插入几个空格,类似于下面这样:sprintf("%s%s -- %s", str_repeat(' ', $path_le ...
- Leetcode 第135场周赛解题报告
这周比赛的题目很有特点.几道题都需要找到一定的技巧才能巧妙解决,和以往靠数据结构的题目不太一样. 就是如果懂原理,代码会很简单,如果暴力做,也能做出来,但是十分容易出错. 第四题还挺难想的,想了好久才 ...
- 推荐一款移动端日历App吉日历
推荐一款移动端日历App吉日历 一 应用描述 万年历.日历.农历.黄历.假期安排.天气预报.记事提醒便捷查看,一目了然! 二 功能介绍: 1.万年历:精美的日期展示,完整的节日日历随意查看,节假日.休 ...
- python2升级python3
需求: centos环境,python2.7需要升级为python3.x 1.请先手动(再次)安装 openssl .否则你升级之后,你的pip不能下载,会各种报错的. 比如这种错误: ImportE ...
- LeetCode 28:实现strStr() Implement strStr()
爱写bug(ID:icodebugs) 作者:爱写bug 实现 strStr() 函数. 给定一个 haystack 字符串和一个 needle 字符串,在 haystack 字符串中找出 needl ...
- 循环节 + 矩阵快速幂 - HDU 4291 A Short problem
A Short problem Problem's Link Mean: 给定一个n,求:g(g(g(n))) % 1000000007 其中:g(n) = 3g(n - 1) + g(n - 2), ...
- Prometheus 编写告警规则案例
Prometheus 编写告警规则案例 注:确保alertmanager配置完毕! 1.创建编辑文件:vim /usr/local/prometheus/rules/node.yml # groups ...