题目链接:F. Restoring the Expression
题意:输入一个字符串,然后让你输出一个加法等式
题解:枚举最后一部分的长度i,前面某一部分的长度只能为i--1或者i.然后用字符串hash先判断是否相等,相等的话在模拟判断一下数值是否相等。
hash[]值用前缀,用b[]保存,对于某一段[l,r]的字符的hash值=(b[r]-(b[l-1]*p[r-l+1])%mod)%mod;p数值的保存的是base的多少次幂取mod.
#include<bits/stdc++.h>
#include<set>
#include<iostream>
#include<string>
#include<cstring>
#include<algorithm>
#define pb push_back
#define ll long long
#define PI 3.14159265
#define ls l,m,rt<<1
#define rs m+1,r,rt<<1|1
#define eps 1e-7
typedef unsigned long long ull;
const ull b1=9973;
const ull b2=100000007;
const int base=10;
const int mod=1e9+7;
const int maxn=1e6+5;
using namespace std;
int n;
ll s[maxn],p[maxn],b[maxn];
char a[maxn];
ll get_val(int l,int r)
{
ll ans=0;
if(r-l+1<=0||l-1<0||r<0)return 0;
ans=(b[r]-(b[l-1]*p[r-l+1])%mod)%mod;
ans=(ans+mod)%mod;
return ans;
}
bool ok(int la,int lb,int lc)
{
int po1=la,po2=la+lb,po3=la+lb+lc;
int tmp=0,up=0;
while(lc--)
{
// tmp=po1>0?s[po1--]:0+po2>la?s[po2--]:0+up;
int t1=po1>0?s[po1--]:0;
int t2=po2>la?s[po2--]:0;
tmp=t1+t2+up;
// cout<<t1<<' '<<t2<<endl;
//cout<<po1>0?s[po1--]:0<<' '<<po2>la?s[po2--]:0<<endl;
up=tmp/10;tmp%=10;
// cout<<tmp<<' '<<up<<' '<<s[po3]<<endl;
if(tmp!=s[po3--])return false;
}
if(up)return false;
for(int i=1;i<=n;i++)
{
if(i==la+1)
{
printf("+");
}
else if(i==la+lb+1)
{
printf("=");
}
printf("%lld",s[i]);
}
printf("\n");
return true;
}
bool slove(int la,int lb,int lc)
{
if(la<1||la>lc||lb>lc||lb<1)return false;
if((lb>1&&s[la+1]==0)||(lc>1&&s[la+lb+1]==0))return false;
ll va=get_val(1,la);
ll vb=get_val(la+1,la+lb);
ll vc=get_val(la+lb+1,la+lb+lc);
if((va+vb)%mod==vc&&ok(la,lb,lc))return true;
else return false;
}
int main()
{
// std::ios::sync_with_stdio(false);
// cin.tie(0);
// cout.tie(0);
scanf("%s",a+1);
n=strlen(a+1);
for(int i=1;i<=n;i++)
{
s[i]=a[i]-'0';
}
p[0]=1;b[0]=0;
for(int i=1;i<=n;i++)
{
b[i]=(b[i-1]*base+s[i])%mod;
p[i]=(p[i-1]*base)%mod;
}
for(int i=1;i<=n;i++)
{
if(slove(i-1,n-i-(i-1),i)||slove(i,n-i-i,i)||slove(n-i-i,i,i)||slove(n-i-(i-1),i-1,i))
{
break;
}
}
return 0;
}