题解:
这题有点麻烦,主要是因为数据太大。。
其实原理好推。
就是i和j为奇数个因子那么 他们的乘积就一定是奇数,满足题意,
接下来就是找,n,m分别的奇数因子的个数。
然后发现 n方 样例 的数因子数都为奇书,
就有转化到,求n,m 开方后的值,然后求积即可。
大数开方比较恶心。 这里采用的是逼近。
证明就不证明了。
#include <stdio.h>
#include <string.h>
#include <iostream>
#include <map>
#include <math.h>
#define LL long long
using namespace std;
const int maxn=1e3+10;
const int mod=1e9+7;
string a,b;
string multi(string a,string b){
string ans="";
int c[maxn]={0};
int i,j;
int lena=a.length();
int lenb=b.length();
for(i=0;i<lena;++i)
for(j=0;j<lenb;++j)
c[lena+lenb-2-i-j]+=(a[i]-'0')*(b[j]-'0');
for(i=0;i<lena+lenb;++i){
if(c[i]>9){
c[i+1]+=c[i]/10;
c[i]=c[i]%10;
}
}
for(i=lena+lenb-1;i;--i)
if(c[i]!=0) break;
for(;i>=0;--i)
ans+=(c[i]+'0');
return ans;
}
int compare(string a,string b,int pos){
int lena=a.length();
int lenb=b.length();
if(lena+pos>lenb) return 1;
if(lena+pos<lenb) return 0;
for(int i=0;i<lena;++i){
if(a[i]-'0'>b[i]-'0') return 1;
if(a[i]-'0'<b[i]-'0') return 0;
}
return 0;
}
string strsqrt(string s){
string ans="";
string t="";
int len=s.length();
if(len%2==0) len=len/2;
else len=len/2+1;
for(int i=0;i<len;i++) {
for(int j=0;j<=9;++j){
t=ans;
t+=j+'0';
if(compare(multi(t,t),s,2*(len-1-i))){
ans+=j-1+'0';
break;
}
if(j==9) ans+='9';
}
}
return ans;
}
int main(){
cin>>a>>b;
string ans=multi(strsqrt(a),strsqrt(b));
int len=ans.length();
for(int i=0;i<len&&ans[i]>='0'&&ans[i]<='9';++i)
printf("%c",ans[i]);
puts("");
return 0;
}