字串雜湊--聰聰的加法等式
阿新 • • 發佈:2018-11-25
題目:
聰聰昨天費了九牛二虎之力終於計算出一個形如
加法算式。
但是調皮的明明,卻將他計算的式子中的加號和等號用橡皮擦去,於是式子只剩下形如
的數字串了。
然而氣急敗壞的聰聰卻怎麼也還原不出原來的等式了,這可怎麼辦呀?你能幫幫他嗎?
長度
solution:
因為和只能和大加數位數一樣活著多一位,所以列舉
,然後雜湊判斷是否合法
順便說單雜湊絕對被卡了,資料居然還卡雙雜湊真是驚了,據說題解是隨機雜湊,然而雙雜湊只要設不那麼常用的模數就可以過了,比如 和 ,我試了一下 都被卡了,不得不說資料實在太強了
#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;
}