【题解】Bzoj3916
字符串\(Hash\).
笔者实在太菜了,到现在还没有熟练掌握\(Hash\),就来这里写一篇学习笔记。
\(Description\)
有三个好朋友喜欢在一起玩游戏,\(A\)君写下一个字符串\(S,B\)君将其复制一遍得到\(T,C\)君在T的任意位置(包括首尾)插入一个字符得到\(U\).现在你得到了\(U\),请你找出\(S.\)
\(Input\)
第一行一个数\(N\),表示\(U\)的长度.
第二行一个字符串\(U\),保证\(U\)由大写字母组成
\(Output\)
输出一行,若S不存在,输出"NOT POSSIBLE".若\(S\)不唯一,输出"NOT UNIQUE".否则输出\(S.\)
字符串\(Hash\),可以快速做到字符串匹配。比如,从一个字符串中选择两个子串进行匹配,还是要\(Hash\)的。
\(Hash\)是一种随机算法。我们设计一个\(Hash\)函数:
设字符串\(C=c_1c_2...c_n\),\(K\)为字符串的长度(前\(K\)个)
选择两个数\(b,h\),满足\(b<h,b\)与\(h\)互质。
我们有:
\(Hash(C,K)=Hash(C,K-1)*b+c_k\)
所以,我们的复杂度瓶颈就在处理\(b\)上了。
对上面的函数拆开来写,就是:
设\(x=m-1\),
\(Hash(C)=(c_1*b^x+...+c_m*1) mod h\)
预处理\(b\)的次幂,递推即可。
考虑一下\(Hash\)冲突的问题。
我们前面取了一个模数\(h=Mod\)对吧。后面我写成\(Mod\).
显然,对于任意串的\(Hash\)值一定是模\(Mod\)意义下剩余系中的一个,可以认为在区间\([0,Mod-1]\)中随机分布。
考虑几个串不相等。
对于第一个串,有\(\frac{Mod-1}{Mod}\)的概率。
如果第二个要和第一个不相等,就只有\(\frac{Mod-2}{Mod}\)的概率。
以此类推,所有串不相等的概率为:
\(\frac{Mod-1}{Mod}*\frac{Mod-2}{Mod}*...*\frac{Mod-i+1}{Mod}\)
\(i\)是子串数(枚举)。
当我们把模数\(1e9\),字符串数达到\(1e5\)的时候,不冲突的概率为:
\(0.006737160911819992\)
在这么大的数据下,显然冲突的概率非常高。如何提高它不冲突的概率?
我们选择模数的时候,发现模数越大,冲突概率越小。那我们就可以利用\(unsigned long long\),自然溢出即可。
还可以双\(Hash\),然而笔者太菜,不会,就先不说了,其实就是在就算一遍\(Hash\)后再计算几遍,只有\(Hash\)值全部相等才算匹配成功。
考虑单\(Hash\)。
这道题,我们的思路就是,枚举断点,然后计算前后两个子串的\(Hash\)是否匹配。
取一段子串的\(Hash\)值时,记住:
当其起点为\(i\),终点为\(j\)时(子串),
\(Hash=H[r]-H[l-1]*power[r-l+1]\)
其中\(H\)数组是计算主串\(Hash\)时计算出来的。
这道题注意一下细节即可。判重的时候,如果与前面有一样的答案,算一个。除非是答案中的字符串不同,才算多重答案。
\(Code:\)
#include<cstdio>
#include<iostream>
#include<cstring>
#include<string>
using namespace std;
typedef unsigned long long ull;
const int B=2333333;
const int H=1e9+9;
int n,vis,L;
ull power[2000010],h[2000010],last;
char s[2000010],a[2000010];
ull Get(int l,int r){return h[r]-h[l-1]*power[r-l+1];}
bool check(int pos){
	ull x,y,z;
	int flag=0;
	if(pos<L){
		x=Get(1,pos-1)*power[L-pos]+Get(pos+1,L);
		y=Get(L+1,n);
	}
	else if(pos>L){
		x=Get(1,L-1);
		y=Get(L,pos-1)*power[n-pos]+Get(pos+1,n);
	}
	else if(pos==L){
		x=Get(1,L-1);
		y=Get(L+1,n);
	}
	if(x==y){
		if(x==last)return 0;
		last=x;
		int top=0;
		if(pos<=L)
			for(int i=L+1;i<=n;++i)
				a[++top]=s[i];
		else
			for(int i=1;i<=L-1;++i)
				a[++top]=s[i];
		return true;
	}
	return 0;
}
int main(){
	scanf("%d",&n);
	scanf("%s",s+1);
	power[0]=1;
	if(n%2==0){
		printf("NOT POSSIBLE\n");
		return 0;
	}
	for(int i=1;i<=n;++i)
		power[i]=power[i-1]*B;
	for(int i=1;i<=n;++i)
		h[i]=h[i-1]*B+s[i];
	L=(n>>1)+1;
	for(int i=1;i<=n;++i){
		vis+=check(i);
		if(vis>1)break;
	}
	if(!vis){
		printf("NOT POSSIBLE\n");
		return 0;
	}
	else if(vis>1){
		printf("NOT UNIQUE\n");
		return 0;
	}
	else puts(a+1);
	return 0;
}
【题解】Bzoj3916的更多相关文章
- 【题解】 bzoj3916: [Baltic2014]friends (字符串Hash)
		题面戳我 Solution 首先长度为偶数可以直接判掉 然后我们可以枚举删的位置,通过预处理的\(hash\),判断剩余部分是否划分成两个一样的 判重要注意,我们把字符串分为三个部分\(L_l+1+L ... 
- 2016 华南师大ACM校赛 SCNUCPC 非官方题解
		我要举报本次校赛出题人的消极出题!!! 官方题解请戳:http://3.scnuacm2015.sinaapp.com/?p=89(其实就是一堆代码没有题解) A. 树链剖分数据结构板题 题目大意:我 ... 
- noip2016十连测题解
		以下代码为了阅读方便,省去以下头文件: #include <iostream> #include <stdio.h> #include <math.h> #incl ... 
- BZOJ-2561-最小生成树 题解(最小割)
		2561: 最小生成树(题解) Time Limit: 10 Sec Memory Limit: 128 MBSubmit: 1628 Solved: 786 传送门:http://www.lyd ... 
- Codeforces Round #353 (Div. 2) ABCDE 题解 python
		Problems # Name A Infinite Sequence standard input/output 1 s, 256 MB x3509 B Restoring P ... 
- 哈尔滨理工大学ACM全国邀请赛(网络同步赛)题解
		题目链接 提交连接:http://acm-software.hrbust.edu.cn/problemset.php?page=5 1470-1482 只做出来四道比较水的题目,还需要加强中等题的训练 ... 
- 2016ACM青岛区域赛题解
		A.Relic Discovery_hdu5982 Time Limit: 2000/1000 MS (Java/Others) Memory Limit: 65536/65536 K (Jav ... 
- poj1399 hoj1037 Direct Visibility 题解 (宽搜)
		http://poj.org/problem?id=1399 http://acm.hit.edu.cn/hoj/problem/view?id=1037 题意: 在一个最多200*200的minec ... 
- 网络流n题 题解
		学会了网络流,就经常闲的没事儿刷网络流--于是乎来一发题解. 1. COGS2093 花园的守护之神 题意:给定一个带权无向图,问至少删除多少条边才能使得s-t最短路的长度变长. 用Dijkstra或 ... 
随机推荐
- 推荐一款强大的前端CLI命令行工具
			背景 命令行界面交互开源工具 CloudBase CLI 自发布以来,受到了大量开发者的欢迎.近期,我们发布了新鲜打磨的 CloudBase CLI 1.0 Beta,引入了许多利于开发者的新特性,下 ... 
- 使用Docker构建PHP7.4 + Swoole + Redis镜像
			使用Docker构建PHP7.4 + Swoole + Redis镜像 Docker是一个用于开发,交付和运行应用程序的开放平台.开发者可以利用Docker来快速交付,测试和部署代码,从而大大减少编写 ... 
- MySQL 外部联结  内连接、左右外连接辨析
			内连接 在进行跨表内连接查询数据时,查询结果只返回符合查询条件的数据:跨表内连接查询的结果和使用where的多表查询结果相同,其实就是普通的查询,没啥好说的 -- 语法: SELECT 别名1.字段名 ... 
- Spring源码分析 手写简单IOC容器
			Spring的两大特性就是IOC和AOP. IOC Container,控制反转容器,通过读取配置文件或注解,将对象封装成Bean存入IOC容器待用,程序需要时再从容器中取,实现控制权由程序员向程序的 ... 
- MPI Maelstrom (Dijstra+atoi函数转换整数)
			BIT has recently taken delivery of their new supercomputer, a 32 processor Apollo Odyssey distribute ... 
- 2019 HNCPC D Modulo Nine 数位DP
			题意 给定长度n和m个限制(l,r),每一个限制的意义是\(a_l \times a_{l+1} \times ... a_r = 0 \quad mod\ 9\). 问有多少个满足所有条件且长度为n ... 
- Java8 ParallelStream
			ParallelStream 并行流就是一个把内容拆分成多个数据块,用不同线程分别处理每个数据块的流.对收集源调用parallelStream方法就能将集合转换为并行流. 并行流 并行流和顺序流转换 ... 
- springboot x.x.x RELEASE不同版本的差异
			springboot 1.x.x RELEASE的 application.properties配置 server.context-path=/ server.port=8080 server.ses ... 
- C#开发PACS医学影像处理系统(三):界面布局之工具栏
			工具栏布局采用WPF中Grid作为容器,按钮采用自定义样式和图标,并采用Separator分割线: XAML设计器代码: 其中 Style="{StaticResource ButtonS ... 
- 初识ABP vNext(9):ABP模块化开发-文件管理
			Tips:本篇已加入系列文章阅读目录,可点击查看更多相关文章. 目录 前言 开始 创建模块 模块开发 应用服务 运行模块 单元测试 模块使用 最后 前言 在之前的章节中介绍过ABP扩展实体,当时在用户 ... 
