F. Restoring the Expression
Problem Statement
A correct expression of the form a+b=c was written; a, b and c are non-negative integers without leading zeros. In this expression, the plus and equally signs were lost. The task is to restore the expression. In other words, one character ‘+’ and one character ‘=’ should be inserted into given sequence of digits so that:
character’+’ is placed on the left of character ‘=’,
characters ‘+’ and ‘=’ split the sequence into three non-empty subsequences consisting of digits (let’s call the left part a, the middle part — b and the right part — c),
all the three parts a, b and c do not contain leading zeros,
it is true that a+b=c.It is guaranteed that in given tests answer always exists.
Input
The first line contains a non-empty string consisting of digits. The length of the string does not exceed 106 .
Output
Output the restored expression. If there are several solutions, you can print any of them.
Note that the answer at first should contain two terms (divided with symbol ‘+’), and then the result of their addition, before which symbol’=’ should be.
Do not separate numbers and operation signs with spaces. Strictly follow the output format given in the examples.
If you remove symbol ‘+’ and symbol ‘=’ from answer string you should get a string, same as string from the input data.
Examples
Example 1
Input
12345168
Output
123+45=168
Example 2
Input
099
Output
0+9=9
Example 3
Input
123123123456456456579579579
Output
123123123+456456456=579579579
题意
给定一个全由数字组成的字符串,让你在中间添加一个加号和一个等号,使它所表示出来的等式成立。且前两个数必为加数,即输出格式为a+b=c。
思路
其实,这题不难。对于一个两个数加法的式子,我们知道,结果最多也只会比最大的那个数多1位,要不结果就和两个加数中大的那个数的位数相等,只有两种情况,于是我们可以这样考虑,对于给出的字符串,我们先进行哈希(我模数取了1e9+7,可以过),然后从右往左枚举结果有几位,那么左边的加数有两种情况,一种是第一个加数与结果位数相等或少1,另一种是第二个加数与结果位数相等或少1,那对于每一位,我们最多只有4种情况,且有很多情况都是无用的。
那么对于一个数如何哈希回来,我们可以对那个字符串进行后缀和,然后对于一个区间[l,r]为一个选定的数,我们就可以通过sum[l]-sum[r+1]来获得这个数哈希以后乘上 10len−r 的值,然后我们要除掉 10len−r ,这个可以通过预处理逆元来完成,最后判一下可不可行,可行直接输出就好了。
Code
#pragma GCC optimize(3)
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
bool Finish_read;
template<class T>inline void read(T &x){Finish_read=0;x=0;int f=1;char ch=getchar();while(!isdigit(ch)){if(ch=='-')f=-1;if(ch==EOF)return;ch=getchar();}while(isdigit(ch))x=x*10+ch-'0',ch=getchar();x*=f;Finish_read=1;}
template<class T>inline void print(T x){if(x/10!=0)print(x/10);putchar(x%10+'0');}
template<class T>inline void writeln(T x){if(x<0)putchar('-');x=abs(x);print(x);putchar('\n');}
template<class T>inline void write(T x){if(x<0)putchar('-');x=abs(x);print(x);}
/*================Header Template==============*/
const ll mod=1e9+7;
int n;
char s[1000010];
ll num[1000010],inv[1000010];
inline ll pw(ll a,ll b) {
ll res=1;
while(b) {
if(b&1)
res=res*a%mod;
a=a*a%mod;
b>>=1;
}
return res;
}
inline void printstr(int l,int r) {
for(int i=l;i<=r;i++)
putchar(s[i]);
}
inline ll calc(int l,int r) {
ll val=((num[l]-num[r+1])%mod+mod)%mod;
// cout<<"interval :"<<l<<"->"<<r<<" get:"<<val<<endl;
return (val*inv[n-r]%mod);
}
inline bool check(ll l1,ll l2,ll l3) {
// cout<<"Now check three lengths:"<<l1<<" and "<<l2<<" and "<<l3<<endl;
if(l1>l3||l2>l3||l1<1||l2<1||l3<1)
return 0;
int pl1=1,pl2=l1+1,pl3=l1+l2+1,pr1=l1,pr2=l1+l2,pr3=l1+l2+l3;
// cout<<"Num one:"<<pl1<<" to "<<pr1<<" Num two:"<<pl2<<" to "<<pr2<<" Num three:"<<pl3<<" to "<<pr3<<endl;
if(s[pl1]=='0'&&pr1-pl1+1!=1)
return 0;
if(s[pl2]=='0'&&pr2-pl2+1!=1)
return 0;
if(s[pl3]=='0'&&pr3-pl3+1!=1)
return 0;
// cout<<"First num:"<<calc(pl1,pr1)<<" Second num:"<<calc(pl2,pr2)<<" Third num:"<<calc(pl3,pr3)<<endl;
if((calc(pl1,pr1)+calc(pl2,pr2))%mod==calc(pl3,pr3)) {
// cout<<pl1<<" "<<pr1<<" "<<pl2<<" "<<pr2<<" "<<pl3<<" "<<pr3<<endl;
printstr(pl1,pr1);
putchar('+');
printstr(pl2,pr2);
putchar('=');
printstr(pl3,pr3);
return 1;
}
return 0;
}
int main() {
// freopen("F.in","r",stdin);
inv[1000000]=pw(10LL,1000000LL);
inv[1000000]=pw(inv[1000000],mod-2);
for(int i=999999;~i;i--)
inv[i]=inv[i+1]*10%mod;
scanf("%s",s+1);
// for(int i=0;i<=10;i++)
// cout<<inv[i]<<endl;
n=strlen(s+1);
// cout<<n<<endl;
// for(int i=1;i<=n;i++)
// putchar(s[i]);
num[n+1]=0;
for(int i=n;i;i--)
num[i]=(num[i+1]+(s[i]-'0')*pw(10LL,n-i)%mod)%mod;
// for(int i=n;i;i--)
// cout<<num[i]<<" ";
// cout<<endl;
for(int div=1;div<=n;div++)
if(check(div-1,n-div-(div-1),div)||check(div,n-div-div,div)||check(n-div-(div-1),div-1,div)||check(n-div-div,div,div))
return 0;
return 0;
}