1. 程式人生 > >字串雜湊--聰聰的加法等式

字串雜湊--聰聰的加法等式

題目:
聰聰昨天費了九牛二虎之力終於計算出一個形如 A + B = C A+B=C 加法算式。
但是調皮的明明,卻將他計算的式子中的加號和等號用橡皮擦去,於是式子只剩下形如 A

B C ABC 的數字串了。
然而氣急敗壞的聰聰卻怎麼也還原不出原來的等式了,這可怎麼辦呀?你能幫幫他嗎?

長度 1 0 6

\le 10^6

solution:
因為和只能和大加數位數一樣活著多一位,所以列舉 A A ,然後雜湊判斷是否合法

順便說單雜湊絕對被卡了,資料居然還卡雙雜湊真是驚了,據說題解是隨機雜湊,然而雙雜湊只要設不那麼常用的模數就可以過了,比如 1

e 9 + 19 1e9+19 998244853 998244853 ,我試了一下 1 e 9 + 7 , 1 e 9 + 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;
}