题目:
聪聪昨天费了九牛二虎之力终于计算出一个形如
A
+
B
=
C
A+B=C
A+B=C 加法算式。
但是调皮的明明,却将他计算的式子中的加号和等号用橡皮擦去,于是式子只剩下形如
A
B
C
ABC
ABC 的数字串了。
然而气急败坏的聪聪却怎么也还原不出原来的等式了,这可怎么办呀?你能帮帮他吗?
长度 ≤ 1 0 6 \le 10^6 ≤106
solution:
因为和只能和大加数位数一样活着多一位,所以枚举
A
A
A,然后哈希判断是否合法
顺便说单哈希绝对被卡了,数据居然还卡双哈希真是惊了,据说题解是随机哈希,然而双哈希只要设不那么常用的模数就可以过了,比如 1 e 9 + 19 1e9+19 1e9+19和 998244853 998244853 998244853,我试了一下 1 e 9 + 7 , 1 e 9 + 9 , 998244353 1e9+7,1e9+9,998244353 1e9+7,1e9+9,998244353都被卡了,不得不说数据实在太强了
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define maxn 1000005
#define int long long
using namespace std;
int n,has1[maxn],has2[maxn],ans,ans2,pw1[maxn],pw2[maxn];
const int bas=10,mod1=1e9+19,mod2=998244853;
char s[maxn];
inline void solve(int len,int i){
int b,res;
b=(has1[n-len]-has1[i]*pw1[n-len-i]%mod1+mod1)%mod1;
res=(has1[n]-has1[n-len]*pw1[len]%mod1)%mod1;
res=(res+mod1)%mod1;
if((has1[i]+b)%mod1!=res) return;
b=(has2[n-len]-has2[i]*pw2[n-len-i]%mod2+mod2)%mod2;
res=(has2[n]-has2[n-len]*pw2[len]%mod2)%mod2;
res=(res+mod2)%mod2;
if((has2[i]+b)%mod2==res) ans=i; return;
}
signed main(){
scanf("%s",s+1); n=strlen(s+1); pw1[0]=pw2[0]=1;
for(int i=1;i<=n;i++){
pw1[i]=pw1[i-1]*bas%mod1;
pw2[i]=pw2[i-1]*bas%mod2;
has1[i]=(has1[i-1]*bas%mod1+s[i]-'0')%mod1;
has2[i]=(has2[i-1]*bas%mod2+s[i]-'0')%mod2;
}
int len,b,res;
for(int i=1;i<=n/2;i++){//枚举A
len=(n-i+1)>>1;
if(len<i) len=i;
if(s[i+1]=='0' && len+i!=n-1) continue;
solve(len,i);
if(ans) {ans2=n-len;break;}
if(len+1+i<n){
++len; solve(len,i);
if(ans) {ans2=n-len;break;}
}
}
for(int i=1;i<=ans;i++) printf("%c",s[i]);
printf("+");
for(int i=ans+1;i<=ans2;i++) printf("%c",s[i]);
printf("=");
for(int i=ans2+1;i<=n;i++) printf("%c",s[i]);
return 0;
}