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 ...
随机推荐
- 深入理解Nginx
nginx概述 nginx是一款自由的.开源的.高性能的HTTP服务器和反向代理服务器:同时也是一个IMAP.POP3.SMTP代理服务器:nginx可以作为一个HTTP服务器进行网站的发布处理,另外 ...
- Learn2Rank
Learning to rank 排序学习是推荐.搜索.广告的核心方法.排序结果的好坏很大程度影响用户体验.广告收入等.排序学习可以理解为机器学习中用户排序的方法,这里首先推荐一本微软亚洲研究院刘铁岩 ...
- supervisor安装及其配置
一.supervisor概述 supervisor是一个c/s系统,被用来在类Unix系统中监控进程状态.supervisor使用python开发. 服务端进程为supervisord,主要负责启动自 ...
- Openresty学习汇总
在锤子科技发布会上,提到给Openresty的捐赠的事情,出于好奇我在是网上查询了Openresty,看到了Openresty的官网(http://openresty.org/en/).看到介绍说的很 ...
- gstreamer调试命令
gplay播放命令 gplay 文件全路径 (eg:gplay 123.mp3) gstreamer播放命令 gst-launch playbin2 uri=file:///文件全路径 (eg gs ...
- 【知识总结】CSS中样式覆盖优先顺序
层叠样式类型 类型: 1. 浏览器默认样式 2. 浏览器用户自定义样式 3. 外部样式表 4. 内部样式表 5. 内联样式表 顺序: 浏览器默认样式 < 浏览器用户自定义样式 < 外部样式 ...
- JavaWeb实现分页的四种方法
一.借助数组进行分页 原理:进行数据库查询操作时,获取到数据库中所有满足条件的记录,保存在应用的临时数组中,再通过List的subList方法,获取到满足条件的所有记录. 实现: 首先在dao层,创建 ...
- Ubuntu安装 Spark2.3.0 报错原因及解决
Ubuntu 安装Spark出现的问题及解决 最近在搭建Hadoop集群环境和Spark集群环境,出现的问题可能不太复杂,纯粹记录安装步骤和问题解决办法.集群环境使用的是(2台)阿里云主机,操作系统是 ...
- SpringMVC 原理和流程
请求到来时,第一个接受这个请求的前端控制器叫DispatcherServlet(这个需要在web.xml中配置),后端控制器叫Controller. 简化版流程: 1.spring mvc将所有的请求 ...
- godaddy之ssl申请
第一步 执行下面命令生成csr和key文件 openssl req -new -newkey rsa: -nodes -keyout trips.com.key -out trips.com.csr ...