CF1056E Check Transcription 题解
作者:互联网
Link.
Description.
给定一个 \(01\) 串 \(s\),保证至少有一个 \(0\) 和 \(1\),有一个目标串 \(t\)。
问有多少种字符串 \(r_0,r_1\),使得把 \(s\) 中 \(0\) 替换成 \(r_0\),\(1\) 替换成 \(r_1\) 后与 \(t\) 相同。
Solution.
设第一个串是 \(0\),方便处理,\(1\) 同理。
枚举 \(|r_0|\),这样 \(r_0\) 确定了,\(|r_1|=\frac{n-c_0\cdot |r_0|}{c_1}\)。
考虑如果算出来的 \(|r_1|\in\mathbb N\),我们就暴力枚举一遍 \(s\),暴力判断所有的 \(s\) 能否匹配。
复杂度算一下发现是 \(O(n\ln n)\) 的,考虑所有长度都不相同,复杂度是 \(O(\frac mi)\),就变成调和级数了。
Coding.
点击查看代码
//Coded by leapfrog on 2021.11.05 {{{
//是啊,你就是那只鬼了,所以被你碰到以后,就轮到我变成鬼了
#include<bits/stdc++.h>
using namespace std;typedef long long ll;
template<typename T>inline void read(T &x)
{
x=0;char c=getchar(),f=0;
for(;c<48||c>57;c=getchar()) if(!(c^45)) f=1;
for(;c>=48&&c<=57;c=getchar()) x=(x<<1)+(x<<3)+(c^48);
f?x=-x:x;
}
template<typename T,typename...L>inline void read(T &x,L&...l) {read(x),read(l...);}//}}}
const int N=100005,P=1019260817;char s[N],t[N*10];int n,m;
struct Hash
{
int has;inline int pls(int x,int y) {return (x+=y)>=P?x-=P:x;}
inline int mns(int x,int y) {return y?pls(x,P-y):x;}
inline bool operator<(const Hash &b) {return has<b.has;}
inline bool operator==(const Hash &b) {return has==b.has;}
inline bool operator!=(const Hash &b) {return has!=b.has;}
inline Hash operator+(const Hash &b) {return(Hash){pls(has,b.has)};}
inline Hash operator-(const Hash &b) {return(Hash){mns(has,b.has)};}
inline Hash operator*(const Hash &b) {return(Hash){int(1ll*has*b.has%P)};}
inline Hash operator+(const int &x) {return(Hash){pls(has,x)};}
inline Hash operator*(const int &x) {return(Hash){int(1ll*has*x%P)};}
}B=(Hash){137},pw[N*10],hs[N*10];
inline Hash geths(int l,int r) {return hs[r]-hs[l-1]*pw[r-l+1];}
int main()
{
scanf("%s%s",s+1,t+1),n=strlen(s+1),m=strlen(t+1);
int rs=0;for(int i=n;i>=1;i--) s[i]^=s[1];
pw[0]=(Hash){1};for(int i=1;i<=m;i++) pw[i]=pw[i-1]*B,hs[i]=hs[i-1]*B+t[i];
int c0=0,c1=0;for(int i=1;i<=n;i++) c0+=!s[i],c1+=s[i];
for(int l0=1;l0<m;l0++)
{
if(m-c0*l0<0) break;else if((m-c0*l0)%c1) continue;
int l1=(m-c0*l0)/c1,L0=-1,R0,L1=-1,R1;char fg=0;if(l1==0) continue;
for(int i=1,nw=1;i<=n&&!fg;i++)
{
if(s[i]) if(L1==-1) L1=nw,R1=(nw+=l1)-1;else fg|=geths(L1,R1)!=geths(nw,nw+l1-1),nw+=l1;
else if(L0==-1) L0=nw,R0=(nw+=l0)-1;else fg|=geths(L0,R0)!=geths(nw,nw+l0-1),nw+=l0;
}rs+=!fg&&(geths(L0,R0)!=geths(L1,R1));
}return printf("%d\n",rs),0;
}
标签:return,int,题解,void,替换成,read,CF1056E,Transcription,inline 来源: https://www.cnblogs.com/pealfrog/p/15512514.html