LOJ2823 三个朋友 ——查询字串的哈希值
概念
查询字串的hash值
我们所说的哈希通常都是进制哈希,因为它具有一些很方便的性质,例如,具有和前缀和类似的性质。
假设一个字符串的前缀哈希值记为 $h[i]$,进制为 $base$,那么显然 $h[i] = h[i-1] \times base + s[i]$.
记 $p[i]$ 为 $base$ 的 $i$ 次方,那么我们可以 $O(1)$ 得到一个字串的哈希值。
typedef unsigned long long ull;
ull get_hash(int l, int r) {
return h[r] - h[l - ] * p[r - l + ];
}
其中,乘以 $p[r-l+1]$ 相当于左移了 $r-l+1$ 位。
同样,我们可以 $O(1)$ 得到字串中删除一个字符后的hash值。
ull get_s(int l, int r, int x) {
return get_hash(l, x - ) * p[r - x] + get_hash(x + , r);
}
例题
题意:给定一个字符串 $S$,先将字符串 $S$ 复制一次,得到字符串 $T$,然后在 $T$ 中插入一个字符,得到字符串 $U$。现给出字符串 $U$,要求重新构造出 $S$。
分析:
枚举每一个位置,剩下的应是两个相同的字符串,根据hash值判断一下。
#include<bits/stdc++.h>
using namespace std; typedef long long ll;
typedef unsigned long long ull;
const ull base = ;
const int maxn = +;
ull h[maxn], p[maxn];
char s[maxn];
int len; void init()
{
ll ans = ;
for(int i=;i<len;i++)
{
ans = (ans*base) + (ull)s[i];
h[i] = ans;
}
p[] = ;
for(int i=;i<=len;i++)
{
p[i] = p[i-]*base;
}
} inline ll gethash(int l,int r)
{
return h[r] - h[l-]*p[r-l+];
} inline ll del(int l,int r,int x)
{
if(x<l||x>r)
return gethash(l,r);
return gethash(l,x-)*p[r-x]+gethash(x+,r);
} inline int check(int x) //检查去掉第x位时是否合法
{
if(x<=len/&&del(,len-,x)==del(,len>>,x)*p[len>>]+del(,len>>,x))
return ;
else if(x>len/&&del(,len-,x)==del(,(len>>)-,x)*p[len>>]+del(,(len>>)-,x))
return ;
else
return ;
} int main()
{
scanf("%d",&len);
scanf("%s",s);
init();
int cnt = ;
int ii = -;
ll num;
for(int i=;i<len;i++)
{
if(check(i))
{
cnt++;
if(ii==-)
{
ii=i;
num = del(,len-,i);
}
else
{
if(del(,len-,ii)==del(,len-,i)) //可能是相同的串
cnt--;
}
}
if(cnt==)
{
printf("NOT UNIQUE\n");
return ;
}
}
if(cnt==)
{
int m = ;
for(int j=;j<len;j++) //输出结果
{
if(j==ii)
continue;
printf("%c",s[j]);
m++;
if(m==(len-)/)
break;
}
printf("\n");
}
if(cnt==)
{
printf("NOT POSSIBLE\n");
}
return ;
}
参考链接:https://loj.ac/submission/576434
LOJ2823 三个朋友 ——查询字串的哈希值的更多相关文章
- 【洛谷1032 】【CJOJ1711】【NOIP2002】字串变换
###题目描述 已知有两个字串 A, B 及一组字串变换的规则(至多6个规则): A1 -> B1 A2 -> B2 规则的含义为:在 A$中的子串 A1 可以变换为 B1.A2 可以变换 ...
- HDU4641 || 6194多校 (后缀自动机-最少出现K次的字串个数 || 恰好出现K次字符串的个数)
http://acm.hdu.edu.cn/showproblem.php?pid=4641 http://acm.hdu.edu.cn/showproblem.php?pid=6194 题意: 开始 ...
- 2019年华南理工大学程序设计竞赛(春季赛) K Parco_Love_String(后缀自动机)找两个串的相同字串有多少
https://ac.nowcoder.com/acm/contest/625/K 题意: 给出Q 个询问 i , 求 s[0..i-1] 与 s[i...len-1] 有多少相同的字串 分析: 给出 ...
- java之字符串中查找字串的常见方法
1.int indexOf(String str) :返回第一次出现的指定子字符串在此字符串中的索引. int indexOf(String str, int startIndex):从指定 ...
- 【字符串】BZOJ上面几个AC自动机求最为字串出现次数的题目
(一下只供自己复习用,目的是对比这几个题,所以写得不详细.需要细节的可以参考其他博主) [BZOJ3172:单词] 题目: 某人读论文,一篇论文是由许多(N)单词组成.但他发现一个单词会在论文中出现很 ...
- 最大公共字串LCS问题(阿里巴巴)
给定两个串,均由最小字母组成.求这两个串的最大公共字串LCS(Longest Common Substring). 使用动态规划解决. #include <iostream> #inclu ...
- 编程:使用递归方式判断某个字串是否回文(Palindrome)
Answer: import java.util.Scanner; public class Palindrome { private static int len;//全局变量整型数据 privat ...
- NOIP2002字串变换[BFS]
题目描述 已知有两个字串 A$, B$ 及一组字串变换的规则(至多6个规则): A1$ -> B1$ A2$ -> B2$ 规则的含义为:在 A$中的子串 A1$ 可以变换为 B1$.A2 ...
- 字串符相关 split() 字串符分隔 substring() 提取字符串 substr()提取指定数目的字符 parseInt() 函数可解析一个字符串,并返回一个整数。
split() 方法将字符串分割为字符串数组,并返回此数组. stringObject.split(separator,limit) 我们将按照不同的方式来分割字符串: 使用指定符号分割字符串,代码如 ...
随机推荐
- Machine Learning Glossary
http://people.seas.harvard.edu/~mgelbart/glossary.html more at:http://www.metacademy.org/list
- Spring Boot 入门(九):集成Quartz定时任务
本片文章续<Spring Boot 入门(八):集成RabbitMQ消息队列>,关于Quartz定时任务请参考<Quartz的基本使用之入门(2.3.0版本)> spring ...
- MappingJackson2JsonView——model转成json
一.ajax请求,返回ModelAndView对象,结果报404: @RequestMapping(value = "/video") public ModelAndView jj ...
- 使用mybatis完成增删改查
插入 插入数据 <insert id="insertUser2" parameterType="UserEntity"> insert into u ...
- Linux下实现web服务器
说明:暂时只是实现了静态网页的响应 #include <stdio.h> #include <sys/types.h> /* See NOTES */ #include < ...
- 创建 Python Virtualenv 虚拟隔离环境
video:创建 Python Virtualenv 虚拟隔离环境 python 虚拟环境 venv 简单用法 - littlemore - 博客园 创建 Python Virtualenv 虚拟隔离 ...
- 使用脚本将AspNetCore发布到IIS上
首先你必须要了解的是,没有脚本的情况下,如何把AspNetCore的应用发布到IIS上. 大致分为这些步骤: 安装MS C++ 2015 x86&x64 安装正确版本的.NET Core Ru ...
- spring的事务解决方案之@Transactional注解
首先此注解位于 org.springframework.transaction.annotation 这个包路径下面, 事务有两种类别,一种是编程式事务,另一种是声明式事务,显然此注解是声明式事务,这 ...
- Vue使用指南(三)
组件 '''1.根组件:new Vue()创建的组件,一般不明确自身的模板,模板就采用挂载点2.局部组件: local_component = {}2.全局组件: Vue.component({})' ...
- Web Services使用SOAP Header
在Web Services方法进行通信使用SOAP遵循标准的SOAP格式,该格式的一部分是在XML文档中编码的数据.XML文档包含一个Envelope根元素(由必需的Body元素和可选的Header元 ...