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 ...
随机推荐
- Hello 2019 Solution
A. Gennady and a Card Game 签到. #include <bits/stdc++.h> using namespace std; ], t[]; bool solv ...
- zwPython,字王集成式python开发平台,比pythonXY更强大、更方便。
zwPython,字王集成式python开发平台,比pythonXY更强大.更方便. 更强大,内置opencv.cuda/opencl.NLTK自然语言.pygame游戏设计等多个重量级模块库. 更方 ...
- ng-深度学习-课程笔记-4: 浅层神经网络(Week3)
1 神经网络概览( Neural Networks Overview ) 先来快速过一遍如何实现神经网络. 首先需要输入特征x,参数w和b,计算出z,然后用激活函数计算出a,在神经网络中我们要做多次这 ...
- Sublime Text3编辑器简介
Sublime Text3编辑器简介 下载地址 绿色中文版v3.3038下载地址:http://www.cncrk.com/downinfo/60832.html 官方网址(英文安装版)下载地址:ht ...
- [Opencv]图像的梯度与边缘检测(转)
文章来源:https://blog.csdn.net/on2way/article/details/46851451 梯度简单来说就是求导,在图像上表现出来的就是提取图像的边缘(不管是横向的.纵向的. ...
- mysql更改数据文件目录及my.ini位置
步骤: 1.查找my.ini位置,可通过windows服务所对应mysql启动项,查看其对应属性->可执行文件路径,获取my.ini路径. "C:\MySQL\MySQL Server ...
- zoj Candies 思维
http://acm.zju.edu.cn/changsha/showProblem.do?problemId=31 题意: 给你n个非负整数,然后输入n个x[i],x[i] == -1表示第i个数不 ...
- Spring ApplicationListener使用方法及二次调用问题解决
使用场景 在一些业务场景中,当容器初始化完成之后,需要处理一些操作,比如一些数据的加载.初始化缓存.特定任务的注册等等.这个时候我们就可以使用Spring提供的ApplicationListener来 ...
- 农历03__ZC
代码,改自 农历01(http://www.cnblogs.com/cppskill/p/5930558.html) 1.main.cpp #include "Lunar_ZC.h" ...
- 一个产生临时图片Url的地方