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;
}