BZOJ---3916:[Baltic2014]friends【哈希】

题意:

假设开始存在一个字符串A,将它复制一遍变成B,有在任意位置插入一个字符得到U,现在给出U,问能否找到初始字符串A

分析:

字符串长度为奇数时才可能找到,然后考虑枚举插入字符的位置,删除这个字符后,剩下的字符中前一半和后一半相等才符合题意,字符串哈希后O(1)判断是否相等

base进制哈希字符串:

hash[i] = hash[i-1]*base+(ull)s[i],让它自然溢出,相当于对2^64取模(别人说的)

根据哈希的规则:

(1)得到一个子串的哈希值就是:hash[R] - hash[L-1]*pow(base,R-L+1)

(2)假设子串S1的哈希值为hash1,S2的哈希值为hash2,两个子串拼接后字符串[S1S2]的哈希值为:hash1*pow(base,strlen(S2))+hash2

此题需要判断初始串A是否唯一,因此要标记前面符合条件的哈希值

代码:

#include <bits/stdc++.h>

using namespace std;
typedef unsigned long long ull;
const int maxn = 2e6+26;
const ull base = 2333;
ull Hash[maxn],Pow[maxn];
char s[maxn];
map<ull,int> vis;
ull cal(int l,int r){
	if(r < l) return 0
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值