CF1056:Check Transcription(被hack的hash)
One of Arkady's friends works at a huge radio telescope. A few decades ago the telescope has sent a signal s s towards a faraway galaxy. Recently they've received a response t t which they believe to be a response from aliens! The scientists now want to check if the signal t t is similar to s s .
The original signal s s was a sequence of zeros and ones (everyone knows that binary code is the universe-wide language). The returned signal t t , however, does not look as easy as s s , but the scientists don't give up! They represented t t as a sequence of English letters and say that t t is similar to s s if you can replace all zeros in s s with some string r 0 r0 and all ones in s s with some other string r 1 r1 and obtain t t . The strings r 0 r0 and r 1 r1 must be different and non-empty.
Please help Arkady's friend and find the number of possible replacements for zeros and ones (the number of pairs of strings r 0 r0 and r 1 r1 ) that transform s s to t t .
Input
The first line contains a string s s (2≤|s|≤10 5 2≤|s|≤105 ) consisting of zeros and ones — the original signal.
The second line contains a string t t (1≤|t|≤10 6 1≤|t|≤106 ) consisting of lowercase English letters only — the received signal.
It is guaranteed, that the string s s contains at least one '0' and at least one '1'.
Output
Print a single integer — the number of pairs of strings r 0 r0 and r 1 r1 that transform s s to t t .
In case there are no such pairs, print 0 0 .
Examples
01
aaaaaa
4
001
kokokokotlin
2
题意:给定一个01串S,和一个字符串T,然后问有多少种方案,使得0和1分别代表一段不同的字符串,使得S==T。
思路:假设S中0的个数的B,1的个数是A,那么就是问多少解Ax+By=C;枚举x,然后hash验证即可。
这里写了几个版本都WA17了。
版本1:双hash,用unsigned int自然溢出。
#include<bits/stdc++.h>
#define ui unsigned int
#define pii pair<ui,ui>
#define F first
#define S second
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
const int seed1=;
const int seed2=;
char a[maxn],b[maxn];
pii p[maxn],Hash[maxn]; int A,B;
int main()
{
int N,M,ans=;
scanf("%s%s",a+,b+);
N=strlen(a+); M=strlen(b+);
rep(i,,N) if(a[i]=='') A++;else B++;
p[].F=p[].S=; rep(i,,M) p[i].F=p[i-].F*seed1,p[i].S=p[i-].S*seed2;
Hash[].F=Hash[].S=;rep(i,,M) Hash[i].F=Hash[i-].F*seed1+b[i],Hash[i].S=Hash[i-].S*seed2+b[i];
rep(i,,M/A){
int x=i,y=(M-x*A)/B; bool F=true;
if(y<||x*A+y*B!=M) continue;
int vis1=-,vis0=-,pos=; pii tag0,tag1;
rep(j,,N){
if(a[j]=='') {
int To=pos+x-; pii tmp;
tmp.F=Hash[To].F-Hash[pos-].F*p[x].F;
tmp.S=Hash[To].S-Hash[pos-].S*p[x].S;
if(vis1==-) vis1=,tag1=tmp;
else if(tmp!=tag1) {F=false; break;}
pos=To+;
}
else {
int To=pos+y-; pii tmp;
tmp.F=Hash[To].F-Hash[pos-].F*p[y].F;
tmp.S=Hash[To].S-Hash[pos-].S*p[y].S;
if(vis0==-) vis0=,tag0=tmp;
else if(tmp!=tag0) {F=false; break;}
pos=To+;
}
}
if(tag0!=tag1&&F) ans++;
}
printf("%d\n",ans);
return ;
}
版本2:双hash,用unsigned long long自然溢出
#include<bits/stdc++.h>
#define ui unsigned long long
#define pii pair<ui,ui>
#define F first
#define S second
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
const ui seed1=;
const ui seed2=;
char a[maxn],b[maxn];
pii p[maxn],Hash[maxn]; int A,B;
int main()
{
int N,M,ans=;
scanf("%s%s",a+,b+);
N=strlen(a+); M=strlen(b+);
rep(i,,N) if(a[i]=='') A++; else B++;
p[].F=p[].S=; rep(i,,M) p[i].F=p[i-].F*seed1,p[i].S=p[i-].S*seed2;
Hash[].F=Hash[].S=;rep(i,,M) Hash[i].F=Hash[i-].F*seed1+b[i],Hash[i].S=Hash[i-].S*seed2+b[i];
rep(i,,M/A){
int x=i,y=(M-x*A)/B; bool Flag=true;
if(y<||x*A+y*B!=M) continue;
int vis1=-,vis0=-,pos=; pii tag0,tag1;
rep(j,,N){
if(a[j]=='') {
int To=pos+x-; pii tmp;
tmp.F=Hash[To].F-Hash[pos-].F*p[x].F;
tmp.S=Hash[To].S-Hash[pos-].S*p[x].S;
if(vis1==-) vis1=,tag1=tmp;
else if(tmp!=tag1) {Flag=false; break;}
pos=To+;
}
else {
int To=pos+y-; pii tmp;
tmp.F=Hash[To].F-Hash[pos-].F*p[y].F;
tmp.S=Hash[To].S-Hash[pos-].S*p[y].S;
if(vis0==-) vis0=,tag0=tmp;
else if(tmp!=tag0) {Flag=false; break;}
pos=To+;
}
}
if(tag0!=tag1&&Flag) ans++;
}
printf("%d\n",ans);
return ;
}
以及各种换种子; 一个用uint,一个用ull; hash时一个直接加,一个加a-48;都是WA。
https://codeforces.com/blog/entry/4898
这里介绍了自然溢出容易被hack,和种子无关。%质数比较保险。 改一下就AC了。以后再也不自然溢出了。
#include<bits/stdc++.h>
#define ui long long
#define ul long long
#define pii pair<ui,ul>
#define F first
#define S second
#define rep(i,a,b) for(int i=a;i<=b;i++)
using namespace std;
const int maxn=;
const ui seed1=;
const ul seed2=;
char a[maxn],b[maxn];
const ui Mod=1e9+;
pii p[maxn],Hash[maxn]; int A,B;
int main()
{
int N,M,ans=;
scanf("%s%s",a+,b+);
N=strlen(a+); M=strlen(b+);
rep(i,,N) if(a[i]=='') A++; else B++;
p[].F=p[].S=; rep(i,,M) p[i].F=p[i-].F*seed1%Mod,p[i].S=p[i-].S*seed2%Mod;
Hash[].F=Hash[].S=;rep(i,,M) Hash[i].F=(Hash[i-].F*seed1%Mod+b[i])%Mod,Hash[i].S=(Hash[i-].S*seed2%Mod+b[i])%Mod;
rep(i,,M/A){
int x=i,y=(M-x*A)/B; bool Flag=true;
if(y<||x*A+y*B!=M) continue;
int vis1=-,vis0=-,pos=; pii tag0,tag1;
rep(j,,N){
if(a[j]=='') {
int To=pos+x-; pii tmp;
tmp.F=((Hash[To].F-Hash[pos-].F*p[x].F%Mod)%Mod+Mod)%Mod;
tmp.F=((Hash[To].S-Hash[pos-].S*p[x].S%Mod)%Mod+Mod)%Mod;
if(vis1==-) vis1=,tag1=tmp;
else if(tmp!=tag1) {Flag=false; break;}
pos=To+;
}
else {
int To=pos+y-; pii tmp;
tmp.F=((Hash[To].F-Hash[pos-].F*p[y].F%Mod)%Mod+Mod)%Mod;
tmp.F=((Hash[To].S-Hash[pos-].S*p[y].S%Mod)%Mod+Mod)%Mod;
if(vis0==-) vis0=,tag0=tmp;
else if(tmp!=tag0) {Flag=false; break;}
pos=To+;
}
}
if(tag0!=tag1&&Flag) ans++;
}
printf("%d\n",ans);
return ;
}
CF1056:Check Transcription(被hack的hash)的更多相关文章
- Codeforces1056E.Check Transcription(枚举+Hash)
题目链接:传送门 题目: E. Check Transcription time limit per test seconds memory limit per test megabytes inpu ...
- [CF1056E]Check Transcription
题目:Check Transcription 传送门:http://codeforces.com/contest/1056/problem/E 分析: 1)显然有个$O( \frac{t}{max(c ...
- CodeForces 1056E - Check Transcription - [字符串hash]
题目链接:https://codeforces.com/problemset/problem/1056/E One of Arkady's friends works at a huge radio ...
- CF1056E Check Transcription 字符串哈希
传送门 暴力枚举\(0\)的长度,如果对应的\(1\)的长度也是一个整数就去check是否合法.check使用字符串哈希. 复杂度看起来是\(O(st)\)的,但是因为\(01\)两个数中数量较多的至 ...
- codeforces gym 101164 K Cutting 字符串hash
题意:给你两个字符串a,b,不区分大小写,将b分成三段,重新拼接,问是否能得到A: 思路:暴力枚举两个断点,然后check的时候需要字符串hash,O(1)复杂度N*N: 题目链接:传送门 #prag ...
- puppeteer(五)chrome启动参数列表API
List of Chromium Command Line Switches https://peter.sh/experiments/chromium-command-line-switches/ ...
- CEF 支持的命令行参数
参考:https://peter.sh/experiments/chromium-command-line-switches/ List of Chromium Command Line Switch ...
- Capabilities & ChromeOptions
https://sites.google.com/a/chromium.org/chromedriver/capabilities http://stackoverflow.com/questions ...
- List of Chromium Command Line Switches(命令行开关集)——官方指定命令行更新网址
转自:http://peter.sh/experiments/chromium-command-line-switches/ There are lots of command lines which ...
随机推荐
- 文件上传—SSM框架文件上传
1.准备上传下载的api组件 <dependency> <groupId>commons-io</groupId> <artifactId>common ...
- 2018-2019 ICPC, NEERC, Northern Eurasia Finals (Unrated, Online Mirror, ICPC Rules, Teams Preferred) Solution
A. Alice the Fan Solved. 题意: 两个人打网球,要求teamA 的得分与其他队伍拉开尽量大 输出合法的方案 思路: $dp[i][j][k][l] 表示 A 赢i局,其他队伍赢 ...
- 服务器环境配置nginx / php / php-fpm(一)
登陆,升级应用,查询和关闭selinux yum update getenforce setenforce 0 vi /etc/selinux 添加非root用户 adduser deploy pas ...
- CentOS6.5下Cloudera安装搭建部署大数据集群(图文分五大步详解)(博主强烈推荐)
不多说,直接上干货! 第一步: Cloudera Manager安装之Cloudera Manager安装前准备(CentOS6.5)(一) 第二步: Cloudera Manager安装之时间服务 ...
- Golang 中的指针 - Pointer
http://www.cnblogs.com/jasonxuli/p/6802289.html Go 的原生数据类型可以分为基本类型和高级类型,基本类型主要包含 string, bool, int ...
- LS1021ATWR开发板启动日志分析
一.背景 LS1021ATWR开发板运行官方的openwrt系统 二.日志分析 2.1 linux相关日志 root@OpenWrt:/# reboot 重启 root@OpenWrt:/# [ 2 ...
- 可替换参数在SharePoint和VS中的使用
什么是可替换参数呢?你可能会在代码里看到像$SharePoint.Project.AssemblyFullName$一样的标记.VS会在编译的时候用完整的签名来替换相应参数.例如,标记 $ShareP ...
- POJ 1860 Currency Exchange(Bellman-Ford)
https://vjudge.net/problem/POJ-1860 题意: 有多种货币,可以交换,有汇率并且需要支付手续费,判断是否能通过不断交换使本金变多. 思路: Bellman-Ford算法 ...
- mong大牛的blog
MongoDB权威指南(3)-查询1.find方法介绍在不传入参数的情况下,find方法缺省使用 http://www.educity.cn/wenda/389594.html 这个归纳的比较好:可 ...
- php多站点配置以及Forbidden You don't have permission to access / on this server问题解决
php多站点配置以及Forbidden You don't have permission to access / on this server问题解决 一.总结 一句话总结:我的问题是php的版本问 ...