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) 我们将按照不同的方式来分割字符串: 使用指定符号分割字符串,代码如 ...
随机推荐
- Python-21-socket编程
一.基础知识 1. C/S架构 C/S架构即客户机/服务器模式. 它可以分为客户机和服务器两层: 第一层: 在客户机系统上结合了界面显示与业务逻辑: 第二层: 通过网络结合了数据库服务器. 简单的 ...
- Redis--hash类型操作命令
哈希类型hash redis hash 是一个 string 类型的 field 和 value 的映射表,hash 特别适合用于存储对象 哈希类型hash——基本命令 hset /hget /hms ...
- golang之文件结尾错误(EOF)
函数经常会返回多种错误,这对终端用户来说可能会很有趣,但对程序而言,这使得情况变得复杂.很多时候,程序必须根据错误类型,作出不同的响应.让我们考虑这样一个例子:从文件中读取n个字节.如果n等于文件的长 ...
- WUSTOJ 1349: TLE(Java)算法优化
题目链接:1349: TLE Description WH在刷题时,设计出了如下代码: #include<stdio.h> int main() { int i, j, cnt, k, N ...
- C++标识符的作用域与可见性
一.标识符的作用域与可见性 作用域讨论的是标识符的有效范围,可见性讨论的是标识符是否可以被引用. 二.作用域 作用域是一个标识符在程序正文中有效的区域.C++中标识符的作用域有函数原型作用域.局部作用 ...
- luogu P4887 莫队二次离线
珂朵莉给了你一个序列$a$,每次查询给一个区间$[l,r]$ 查询$l≤i<j≤r$,且$ai⊕aj$的二进制表示下有$k$个$1$的二元组$(i,j)$的个数.$⊕$是指按位异或. 直接暴力莫 ...
- 深度学习的激活函数 :sigmoid、tanh、ReLU 、Leaky Relu、RReLU、softsign 、softplus、GELU
深度学习的激活函数 :sigmoid.tanh.ReLU .Leaky Relu.RReLU.softsign .softplus.GELU 2019-05-06 17:56:43 wamg潇潇 阅 ...
- hdu 1075 map的使用 字符串截取的常用手段 以及string getline 使用起来的注意事项
首先说字符串的截取套路吧 用坐标一个一个的输入 用遍历的方式逐个去检查字符串中的字符是否为符合的情况 如果是的话 把该字符放入截取string 中 让后坐标前移 如果不是的话 截取结束 坐标初始化 然 ...
- Spark机器学习基础-特征工程
对连续值处理 0.binarizer/二值化 from __future__ import print_function from pyspark.sql import SparkSession fr ...
- 修改docker容器端口映射的方法
大家都知道docker run可以指定端口映射,但是容器一旦生成,就没有一个命令可以直接修改.通常间接的办法是,保存镜像,再创建一个新的容器,在创建时指定新的端口映射. 有没有办法不保存镜像而直接修改 ...