Non Super Boring Substring 题解(hash+思维)
题目链接
题目大意
给你一个长度为d(d<=1e5)的字符串,要你求有多少个子串满足这个子串不包含长度大于等于k的回文子串
题目思路
首先可以hash预处理,然后O(1)用前缀hash值和后缀hash值求一个字符串是否是回文串
其实你只要枚举每个点当作左端点,求右端点最远能到那里即可
回文串可能最多达到\(n^2\)个,但你可以思考一下其实你只要考虑长度为k和k+1的字符串即可
具体证明有点麻烦自己可以画图去考虑一下,因为长度更长的回文串必有子串长度为k或k+1
但是长度更短的回文串,影响明显是比长度更大的回文串大,即可以使得左端点固定,右端点更左
然后把所有长度为k或者k+1的回文串,先按右端点,然后按左端点排序
用双指针的思想求出每个点当作左端点,可以到达的最远右端点
代码
#include<set>
#include<map>
#include<queue>
#include<stack>
#include<cmath>
#include<cstdio>
#include<vector>
#include<string>
#include<cstring>
#include<iostream>
#include<algorithm>
#include<unordered_map>
#define fi first
#define se second
#define debug printf(" I am here\n");
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
const ll INF=0x3f3f3f3f3f3f3f3f;
const int maxn=1e5+5,inf=0x3f3f3f3f,mod=2017;
const double eps=1e-10;
int k;
char s[maxn];
int d;
ull base[maxn],pre[maxn],suf[maxn];
pair<int,int> pa[maxn];
void init(){
base[0]=1;
for(int i=1;i<=d;i++){
base[i]=base[i-1]*29;
}
for(int i=1;i<=d;i++){
pre[i]=pre[i-1]*29+s[i]-'a'+1;
}
for(int i=d;i>=1;i--){
suf[i]=suf[i+1]*29+s[i]-'a'+1;
}
}
ll getprehash(int l,int r){
return pre[r]-pre[l-1]*base[r-l+1];
}
ll getsufhash(int l,int r){
return suf[l]-suf[r+1]*base[r-l+1];
}
int main(){
int _;scanf("%d",&_);
while(_--){
scanf("%d %s",&k,s+1);
d=strlen(s+1);
init();
int cnt=0;
for(int i=1;i+k-1<=d;i++){
if(getprehash(i,i+k-1)==getsufhash(i,i+k-1)){
pa[++cnt]={i+k-1,i};
}
}
for(int i=1;i+k+1-1<=d;i++){
if(getprehash(i,i+k)==getsufhash(i,i+k)){
pa[++cnt]={i+k,i};
}
}
sort(pa+1,pa+1+cnt);
int now=1;
ll ans=0;
for(int i=1;i<=d;i++){
while(pa[now].se<i&&now<=cnt){
now++;
}
if(now==cnt+1){
ans+=d-i+1;
}else{
ans+=pa[now].fi-1-i+1;
}
}
printf("%lld\n",ans);
}
return 0;
}
Non Super Boring Substring 题解(hash+思维)的更多相关文章
- LeetCode longest substring without repeating characters 题解 Hash表
题目 Given a string, find the length of the longest substring without repeating characters. Example 1: ...
- COGS 902 乐曲主题 题解 & hash入门贺
[题意] 给定一个长为n的序列,元素都是不超过88的正整数,求序列中主题的最大长度. 所谓主题是指在序列中出现了至少两次并且不相交的子串.特别的,主题可以变调,也就是说如果一个子串全部加上或减去一个数 ...
- [LeetCode]Longest Palindromic Substring题解(动态规划)
Longest Palindromic Substring: Given a string s, find the longest palindromic substring in s. You ma ...
- Codeforces Round #579 (Div. 3) D2. Remove the Substring (hard version) (思维,贪心)
题意:给你一个模式串\(t\),现在要在主串\(s\)中删除多个子串,使得得到的\(s\)的子序列依然包含\(t\),问能删除的最长子串长度. 题解:首先,我们不难想到,我们可以选择\(s\)头部到最 ...
- CF1433A Boring Apartments 题解
Content 我们把仅由一个或多个相同的数位组成的数字叫作"无聊的数字".我们把 \(\leqslant 10000\) 的这种数字按照以下规则排列: 首先,将仅由 \(1\) ...
- Find the Maximum - 题解【思维,贪心】
题面 这是2022年ICPC昆明站的F题.在赛场上,我一开始敲了个贪心,但是出锅了,改敲树形DP,但是时间来不及了.在队友的提醒下补过了这个题,知道解法的我发现我就是个纯纯的老坛-- 原题链接在牛客网 ...
- [NOIP2015] 子串substring 题解
[题目描述] 有两个仅包含小写英文字母的字符串A和B.现在要从字符串A中取出k个互不重叠的非空子串,然后把这k个子串按照其在字符串A中出现的顺序依次连接起来得到一个新的字符串,请问有多少种方案可以使得 ...
- BZOJ2555:SubString——题解
https://www.lydsy.com/JudgeOnline/problem.php?id=2555 (1):在当前字符串的后面插入一个字符串 (2):询问字符串s在当前字符串中出现了几次?(作 ...
- 牛客练习赛16 B 漂亮的树【哈希hash/思维】
链接:https://www.nowcoder.com/acm/contest/84/B 来源:牛客网 题目描述 街上有n棵树,标号为1...n,第i棵树的高度为ai. 定义这n棵树是漂亮的,当且仅当 ...
随机推荐
- String字符串性能优化的探究
一.背景 String 对象是我们使用最频繁的一个对象类型,但它的性能问题却是最容易被忽略的.String 对象作为 Java 语言中重要的数据类型,是内存中占用空间最大的一个对象,高效地使用字符串, ...
- git 上传代码报错eslint --fix found some errors. Please fix them and try committing again.
在提交时用下面这句 git commit --no-verify -m "提交时的注释"
- Redis常用命令(4)——List
BLPOP 格式:BLPOP key [key ...] timeout 作用:从列表左侧弹出元素,超时时间为timeout,单位为秒.如果timeout为0则一直阻塞直到列表中有元素.如果同时操作多 ...
- Java学习的第六天
1.今天学习了各种运算符, 还有选择结构,循环结构 2.今天学习没有遇到困难. 3.明天学习数组和第三章的开头一部分.
- 常用数据结构-namedtuple(命名元祖)
namedtuple从根本上来说是一个带有数据名称的元祖.它包含元祖的所有特性,但也有一些元祖没有的额外特性.使用namedtuple可以很容易创建轻量级对象类型. namedtuple将是你的代码更 ...
- [Luogu P2261] [CQOI2007]余数求和 (取模计算)
题面 传送门:https://www.luogu.org/problemnew/show/P2261 Solution 这题显然有一个O(n)的直接计算法,60分到手. 接下来我们就可以拿出草稿纸推一 ...
- 一年前,我来到国企搞IT
2020.11.01日,这一天是我加盟xxx国企的一年整,这篇分享本来是要提前写的,不过由于前段时间确实繁忙,一直没有机会提笔.今天简单和大家分享下我在国企的一些工作内容,感悟等等,希望能给那些对 ...
- 想更改Github仓库中的某个文件结构
虽然有各种版本回退啥的,可是感觉好麻烦,还是没搞来,后来发现可以直接先删除,然后在本地更改,更改完之后重新添加一次即可 删除远程库的某个文件: $ git pull origin master 将远程 ...
- git commit后如何取消commit
在git使用中要如何取消commit但是还未push的操作? 通常,我们对修改的文件会先git add .,然后git commmit -m "注释",但是如果commit错了,想 ...
- 402. 移掉K位数字
给定一个以字符串表示的非负整数 num,移除这个数中的 k 位数字,使得剩下的数字最小. 注意: num 的长度小于 10002 且 ≥ k.num 不会包含任何前导零.示例 1 : 输入: num ...