hdu 5157(manacher+前缀和+树状数组)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5157
解题思路:
我们可以先用mancher算法对字符串进行处理,把以每个点为中心的回文串半径求出来,然后进行处理。
加入对以p为中心的点,从p-r[i]+1~p都是回文串的开头,那么对于每个回文串(开头是j)只要记录结尾从1~j-1的回文串个数,我们可以用dp记录以每个点为结尾的回文串个数,s[i]=sigma(dp[i]),则是结尾从1~j-1的回文串个数。那么对这个中心点来说一共的回文串对应该有:s[p-r[i]]+...+s[p-1]个,那么我们可以继续用一个数组s1[i]求s[i]的前缀和,那么总复杂度是O(n)。
至于dp[i]怎么求,你已经知道了半径,那从p~p+r[i]-1这些点的dp值都要加1,可以用树状数组来维护。
参考博客:http://blog.csdn.net/u013665921/article/details/42552603
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;typedef long long LL;
char c[200005],f[100005];
int r[200005],tree[200005];
LL s[200005],s1[200005];int low(int n)
{return n & -n;
}void merg(int p,int n,int k)
{while(p<=n){tree[p]+=k;p=p+low(p);}
}int sum(int p)
{int s=0;while(p>0){s+=tree[p];p=p-low(p);}return s;
}void mancher(int n)
{int id;r[0]=1;id=0;for(int i=1; i<=2*n; i++){if(r[id]+id > i) r[i] = min(r[2*id-i],r[id]+id-i);else r[i] = 1;while(i-r[i]>=0 && i+r[i]<=2*n && c[i-r[i]]==c[i+r[i]]) r[i]++;if(i+r[i] > id+r[id])id=i;}
}void get_back(int n)
{memset(tree,0,sizeof(tree));for(int i=1;i<=2*n;i++){int p=i+r[i]-1;if(i%2==0){if(p>i){merg(i/2+1,n,1);merg(p/2+1,n,-1);}}else{merg((i+1)/2,n,1);merg(p/2+1,n,-1);}}s[0]=0;s1[0]=0;for(int i=1;i<=n;i++){s[i]=s[i-1]+sum(i);s1[i]=s1[i-1]+s[i];}
}void work(int n)
{LL ans=0;int i,j;for(i=1;i<=2*n;i++){if(i % 2 == 0 && r[i] > 1)ans+=s1[i/2-1]-s1[(i-r[i]+1)/2-1];else if(i % 2 == 1)ans+=s1[(i+1)/2-1]-s1[(i-r[i]+1)/2-1];}cout << ans << endl;
}int main()
{int i,j,n;while(scanf("%s",f)!=EOF){n = strlen(f);c[0] = '#';for(i=1;i<=n;i++){c[2*i] = '#';c[2*i-1] = f[i-1];}mancher(n);get_back(n);work(n);}return 0;
}
hdu 5157(manacher+前缀和+树状数组)相关推荐
- HDU 1556 前缀和 树状数组 线段树
解法一: a[i]表示以 i作为起点,对 i-n的气球全部上色的次数 对(start,end)区间上色 ++a[start] --a[end+1]抵消掉 end+1-n的部分 问题转换为求 a的前缀 ...
- HDU 3333 Turing Tree(树状数组/主席树)
题意 给定一个长度为 \(n\) 的序列,\(m\) 个查询,每次查询区间 \([L,R]\) 范围内不同元素的和. \(1\leq T \leq 10\) \(1 \leq n\leq 300 ...
- HDU 5517---Triple(二维树状数组)
题目链接 Problem Description Given the finite multi-set A of n pairs of integers, an another finite mult ...
- hdu 6447YJJ's Salesman 离散化+树状数组+DP
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=6447 因为图中点的坐标值过大,达到1e9.然而只有1e5个点.所以先将其离散化.并按照<x.y& ...
- [HDU - 2852] KiKi's K-Number (树状数组+二分)
链接 http://acm.hdu.edu.cn/showproblem.php?pid=2852 题意 现在需要你对一个空序列做nnn次操作,操作分三种 0x0\ \ x0 x :向序列中加入一个 ...
- HDU - 5775 - Bubble Sort( 树状数组 + 思维 )
题目链接:点击进入 题目 题意 问在给出的冒泡排序过程中,一个数到达的最右边位置与最左边位置距离差. 思路 对于一个数,位置 i ,假设右边比它小的数有 r 个,左边比它大的数有 l 个,最右边到达的 ...
- POJ 3928 hdu 2492 Uva1428 PingPong 【树状数组】
Ping pong Time Limit: 2000/1000 MS (Java/Others) ...
- HDU 3584 Cube (三维树状数组)
Problem Description Given an N*N*N cube A, whose elements are either 0 or 1. A[i, j, k] means the nu ...
- HDU 3015 Disharmony Trees(树状数组)
题意:给你n棵树,每棵树上有两个权值X H 对于X离散化 :3 7 1 5 3 6 -> 2 6 1 4 2 5,对于H一样 然后F = abs(X1-X2) S=min(H1,H2) 求出 ...
最新文章
- 代码整理工具_程序员软件:程序员有哪些常用又好用的编码小工具?
- 十一课堂|通过小游戏学习Ethereum DApps编程(4)
- Java9新特性系列(模块化系统: Jigsaw-Modularity)
- day for people, night for material
- 天堂Lineage(單機版)從零開始架設教學 Installing Lineage 3.52 Server - On Windows
- JS性能分析(测试代码运行时间)
- 加入 Git 版本管理(git的基本使用)
- hdu 1421 搬寝室 动态规划
- mongodb和mysql创建表_MongoDB 数据库创建删除、表(集合)
- POJ-2480 Longge's problem 欧拉函数
- Auto Layout详解
- 怎样在VMWare虚拟机中的Windows系统使用U盘启动盘进入PE环境
- 软考中级网络工程师笔记(一)
- EDA技术及应用实验2 or2a程序
- 什么是AHP 层次分析法?
- 组合导航初始对准(1)
- js逆向-知乎最新x-zse-96 逆向源码(2022-09-25更新)
- 结构方程模型amos软件一些常见的处理问题
- 【工作记录】支付系统数据库梳理
- 第五章 数据库设计和事务 ① 笔记