[CSP-S模拟测试]:回文(hash+二维前缀和)
题目描述
闲着无聊的$YGH$秒掉上面两道题之后,开始思考有趣的回文串问题了。
他面前就有一个漂浮着的字符串。显然$YGH$是会$manacher$的,于是他随手求出了这个字符串的回文子串个数。但是他不满足于这个问题,他打算搞出一个数据结构,能够快速求出这个字符串下标为$[l,r]$的子串的回文子串个数(相同的回文子串需重复计数)。但是这实在是太简单啦,他打算考考辣鸡$YYR$,可是辣鸡至极的$YYR$完全没有思路。
于是,$YGH$扬长而去,在衣袖带起的一小片尘土之中,沉思的$YYR$依旧在那里。
输入格式
第一行为一个字符串$S$。
第二行一个整数$T$,表示询问次数。
接下来$T$行,每行两个整数$l$、$r$,表示查询字符串$S$下标为$[l,r]$的子串的答案。
输出格式
输出$T$行,每行一个整数表示这个询问的答案。
样例
样例输入:
ababaab
2
1 3
3 7
样例输出:
4
8
数据范围与提示
对于$20\%$的数据,保证$|S|,T\leqslant 500$
对于$40\%$的数据,保证$|S|,T\leqslant 5,000$
对于$100\%$的数据,保证$|S|\leqslant 5,000,T\leqslant 100,000$
题解
先来将问题更加抽象化,定义一个二维数组$Map$,如果区间$[l,r]$是回文串,那么$Map[l][r]=1$,否则为$0$。
那么,我们所需要求的就是点$(l,l)$到点$(r,r)$直接有几个$1$。
前面求是不是回文串的过程可以用$hash$实现,后面求$1$的个数可以用前缀和。
时间复杂度:$\Theta(n^2+T)$。
期望得分:$100$分。
实际得分:$100$分。
代码时刻
#include<bits/stdc++.h>
using namespace std;
int n;
char ch[5001];
int S[5001];
int Map[5001][5001];
unsigned long long flag[5001];
unsigned long long hash1[5001],hash2[5001];
void pre_work()
{
flag[0]=1;
for(int i=1;i<=n;i++)
{
flag[i]=flag[i-1]*131;
hash1[i]=hash1[i-1]*131+S[i];
}
for(int i=n;i;i--)hash2[i]=hash2[i+1]*131+S[i];
for(int i=1;i<=n;i++)
for(int j=i;j<=n;j++)
if(hash1[j]-hash1[i-1]*flag[j-i+1]==hash2[i]-hash2[j+1]*flag[j-i+1])
Map[i][j]=1;
for(int i=1;i<=n;i++)
for(int j=1;j<=n;j++)
Map[i][j]+=Map[i-1][j]+Map[i][j-1]-Map[i-1][j-1];
}
int main()
{
scanf("%s",ch+1);
n=strlen(ch+1);
for(int i=1;i<=n;i++)
S[i]=ch[i]-'a'+1;
pre_work();
int T;scanf("%d",&T);
while(T--)
{
int l,r;
scanf("%d%d",&l,&r);
printf("%d\n",Map[r][r]-Map[l-1][r]-Map[r][l-1]+Map[l-1][l-1]);
}
return 0;
}
rp++
[CSP-S模拟测试]:回文(hash+二维前缀和)的更多相关文章
- [CSP-S模拟测试]:任(duty)(二维前缀和)
题目描述 $liu\_runda$退役之后就失去梦想开始咸鱼生活了……$Bilibili$夏日画板活动中,所有人都可以在一块画板上进行像素画创作.$UOJ$群有一群无聊的人决定在画板上创作一个$50\ ...
- [CSP-S模拟测试]:回文串(hash+二分)
题目描述 $ASDFZ$的机房中不仅有红太阳,还有蓝太阳和原谅色太阳.有一天,太阳们来到机房,发现桌上有不知道哪个蒟蒻放上的问题:令$F(A,B)$表示选择一个串$A$的非空前缀$S$和串$B$的非空 ...
- 回文数二(acm训练)
问题 1161: [回文数(二)] 时间限制: 1Sec 内存限制: 128MB 提交: 133 解决: 51 题目描述 若一个数(首位不为零)从左向右读与从右向左读都一样,我们就将其称之为回文数. ...
- [CSP-S模拟测试]:physics(二维前缀和+二分+剪枝)
题目传送门(内部题26) 输入格式 第一行有$3$个整数$n,m,q$.然后有$n$行,每行有一个长度为$m$的字符串,$+$表示正电粒子,$-$表示负电粒子.然后有$q$行,每行$2$个整数$x,y ...
- 计蒜客模拟赛D1T1 蒜头君打地鼠:矩阵旋转+二维前缀和
题目链接:https://nanti.jisuanke.com/t/16445 题意: 给你一个n*n大小的01矩阵,和一个k*k大小的锤子,锤子只能斜着砸,问只砸一次最多能砸到多少个1. 题解: 将 ...
- 【题解】洛谷P2822 [NOIP2016TG ]组合数问题 (二维前缀和+组合数)
洛谷P2822:https://www.luogu.org/problemnew/show/P2822 思路 由于n和m都多达2000 所以暴力肯定是会WA的 因为整个组合数是不会变的 所以我们想到存 ...
- Nowcoder farm ( 树状数组、二维前缀和、二维偏序 )
题目链接 分析 : 最简单的想法当然就是去模拟 直接对每个施肥料的操作进行模拟.然后计算贡献 但是这显然会超时.这题需要换一个思维 对于一个土地(也就是二维平面上的一个点)的种类是 T' 如果它被操作 ...
- 【AcWing 99】激光炸弹——二维前缀和
(题面来自AcWing) 一种新型的激光炸弹,可以摧毁一个边长为 R 的正方形内的所有的目标. 现在地图上有 N 个目标,用整数Xi,Yi表示目标在地图上的位置,每个目标都有一个价值Wi. 激光炸弹的 ...
- openjudge1768 最大子矩阵[二维前缀和or递推|DP]
总时间限制: 1000ms 内存限制: 65536kB 描述 已知矩阵的大小定义为矩阵中所有元素的和.给定一个矩阵,你的任务是找到最大的非空(大小至少是1 * 1)子矩阵. 比如,如下4 * 4的 ...
随机推荐
- Numpy 里线性代数函数
c
- Jmeter的中英文互换
1.jmeter的中英文互换:为了更深入的了解Jmeter,一般使用英文版的jmeter. 旧版本下载的默认中文较多.新版本5.1的下载后默认英文比较的多. 方法一: 选项->选择一种语言,但是 ...
- C++笔记(4)——引用及结构体
引用 C++中有一个很方便的语法叫做引用,作用就是使得函数能够对传入的参数作出全局有效的改动.用法很简单,就是在传入参数的类型后面加上&就可以指明传入的参数是引用. 例子: #include ...
- Http中Content-Type的取值讲解
一.Content-Type的取值 在Http请求中,我们每天都在使用Content-type来指定不同格式的请求信息(MediaType,即是Internet Media Type,互联网媒体类型: ...
- 如何通过脚本实现显示版本号、CPU、硬盘和内存条大小
COLOR="\033[1;$[RANDOM%7+31]m" COLOR1="\033[1;$[RANDOM%7+31]m"COLOR2="\ ...
- 来自python自学者的小问题
我想使用python的第三方库,但是我的IDE给我一个错误代码: D:\untitled\venv\Scripts\python.exe "D:/py code/venv/sxsxsxsxs ...
- 极*Java速成教程 - (3)
Java语言基础 访问权限控制 Java是一个面向对象的语言,当你不是它所设计的要面向的对象时,它就不会给你看你不该看到的东西,也就是"访问权限控制". 亲疏有别,才能权限控制 包 ...
- java 标识接口的作用
标识接口的作用 标识接口是没有任何方法和属性的接口.标识接口不对实现它的类有任何语义上的要求,它仅仅表明实现它的类属于一个特定的类型. 标接口在Java语言中有一些很著名的应用,例如我们常用的Arra ...
- Webpack4、iView、Vue开发环境的搭建
导读 项目使用了 yarn ,一个快速.可靠.安全的依赖管理工具.yarn 是一个类似于npm的包管理工具,它是由 facebook 推出并开源,它在速度,离线模式,版本控制的方面具有独到的优势.此项 ...
- SQL 中的正则函数
ORACLE中支持正则表达式的函数主要有下面四个: 1,REGEXP_LIKE :与LIKE的功能相似,比LIKE强大得多. 2,REGEXP_INSTR :与INSTR的功能相似. 3,REGEXP ...