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 ...
随机推荐
- devise 自定义手机号登录
user model中配置 validates_uniqueness_of :phone def email_required? false end 修改user migration文件,给phone ...
- hdu5880 Family View
地址:http://acm.split.hdu.edu.cn/showproblem.php?pid=5880 题目: Family View Time Limit: 3000/1000 MS (Ja ...
- 分布式session的管理
在分布式架构或微服务架构下,必须保证一个应用服务器上保存Session后,其它应用服务器可以同步或共享这个Session,可能会出现在A1系统登录后创建并保存Session,再次发起请求,请求被转发到 ...
- mongodb的安装和权限管理
mongodb4.0已经发布,但是鉴于线上环境更多的是使用旧版本的mongodb,我们这里使用的mongodb3.4版本. 官网下载地址为:https://fastdl.mongodb.org/lin ...
- bzoj1610 / P2665 [USACO08FEB]连线游戏Game of Lines
P2665 [USACO08FEB]连线游戏Game of Lines 第一次写快读没判负数....(捂脸) 暴力$O(n^2)$求斜率,排序判重. 注意垂直方向的直线要特判. end. #inclu ...
- Django:提交表单时遇到403错误:CSRF verification failed
Django:提交表单时遇到403错误:CSRF verification failed 问题: 提交表单时遇到403错误:CSRF verification failed 解决方案: 在表单界面ht ...
- SQL Server2008创建数据库语法
use mastergo if exists(select * from sys.databases where name='MySchool') drop database MySchool -- ...
- shell脚本中多个条件判断的语法
if [ "$content" = "hello" ]\ || [ "$content" = "kitty" ] the ...
- spring Boot加载bean
1.SpringBoot中加载bean,可以使用注解@compenent直接加载到applicationContext容器中 2.在直接类@Configuration中,手动注册bean,如:
- luogu P1162 填涂颜色
https://www.luogu.org/problem/show?pid=1162 //其实很简单的吧 //就是最外圈加一圈0 ,然后把外圈里面的0都遍历了 //剩下的0 就变成2 就行了 #in ...