支持 加、减、乘、除、开方运算,保留整数位
#include<iostream>
#include<cstdlib>
#include<cstring>
#include<vector>
#include<cstdio>
using namespace std;
struct hac
{
vector<int> a;
bool flag;
hac con()const //符号取反
{
hac temp=*this;
temp.flag=!temp.flag;
return temp;
}
void store(string str="")
{
string t;
int temp;
flag=(str[0]!='-');
if(!flag||str[0]=='+')
str.erase(0,1);
while(str.length()%4!=0)str='0'+str; //高位补零
a.push_back(str.length()/4);//位数
for(int i=0;i<a[0];i++)
{
t=str.substr(str.length()-4,4);
temp=1000*(t[0]-'0')+100*(t[1]-'0')+10*(t[2]-'0')+(t[3]-'0');
a.push_back(temp);
str.erase(str.length()-4,str.length()-1);
}
}
bool operator==(const hac x)const
{
if(flag!=x.flag||a[0]!=x.a[0])return false;
for(int i=1;i<=a[0];i++)
if(a[i]!=x.a[i])
return false;
return true;
}
bool operator<(const hac x)const
{
if(!flag&&x.flag)return true;
if(flag&&!x.flag)return false;
if(!flag&&!x.flag)
return x.con()<(*this).con();
if(a[0]<x.a[0])return true;
if(a[0]>x.a[0])return false;
int i=a[0];
while(i>=1&&a[i]==x.a[i])i--;
if(i>=1)
return a[i]<x.a[i];
return false;
}
bool operator>(const hac x)const
{
return x<*this;
}
bool operator<=(const hac x)const
{
return !(*this>x);
}
bool operator>=(const hac x)const
{
return !(*this<x);
}
hac operator+(hac b)const
{
hac ans=*this;
int i;
if(ans.flag&&b.flag)
{
if(ans.a[0]<b.a[0])return b+ans;
ans.a.push_back(0);
ans.a.push_back(0);
for(i=1;i<=b.a[0];i++)
ans.a[i]+=b.a[i];
for(i=1;i<=ans.a[0];i++)
while(ans.a[i]>=10000){ans.a[i+1]+=ans.a[i]/10000;ans.a[i]%=10000;}
while(ans.a[ans.a[0]+1]!=0)ans.a[0]++;
return ans;
}
else if(!ans.flag&&b.flag)
{
ans.flag=true;
return b-ans;
}
else if(ans.flag&&!b.flag)
{
b.flag=true;
return ans-b;
}
else
{
ans.flag=true;
b.flag=true;
return (ans+b).con();
}
}
hac operator-(hac b)const
{
hac ans=*this;
if(!ans.flag&&!b.flag)
{
return (b.con()-ans.con());
}
if(ans<b){return (b-ans).con();}
if(!ans.flag)
{
return (ans.con()+b).con();
}
if(!b.flag)
{
return ans+b.con();
}
for(int i=1;i<=b.a[0];i++)
ans.a[i]-=b.a[i];
for(int i=1;i<=ans.a[0];i++)
while(ans.a[i]<0)
{
ans.a[i+1]--;
ans.a[i]+=10000;
}
while(ans.a[ans.a[0]]==0&&ans.a[0]>1)ans.a[0]--;
return ans;
}
hac operator*(hac b)const
{
hac temp=*this;
vector<int> c(temp.a[0]+b.a[0]+2);
int i,j;
if(!b.flag)temp.flag=!temp.flag;
c[0]=temp.a[0]+b.a[0]-1;
for(i=1;i<=temp.a[0];i++)
for(j=1;j<=b.a[0];j++)
{
c[i+j-1]+=(temp.a[i]*b.a[j]);
c[i+j]+=(c[i+j-1]/10000);
c[i+j-1]%=10000;
}
temp.a=c;
while(temp.a[temp.a[0]+1]!=0)temp.a[0]++;
return temp;
}
hac div2()
{
a[1]/=2;
for(int i=2;i<=a[0];i++)
{
if(a[i]%2)a[i-1]+=5000;
a[i]/=2;
}
if(!a[a[0]])a[0]--;
return *this;
}
hac operator/(hac b) //二分法,求整数商
{
if(!flag&&!b.flag)return con()/b.con();
if(!flag&&b.flag)return (con()/b).con();
if(flag&&!b.flag)return (*this/b.con()).con();
hac l,r,m,one;
string s="";
l.store("0");
one.store("1");
for(int i=1;i<=a[0]-b.a[0]+1;i++)s+="0000";
s='1'+s;
m.store(s);
r=m*b;
while(l+one<r)
{
m=(l+r).div2();
if(m*b==*this) return m;
(m*b>=*this)? r=m:l=m;
}
return l;
}
void print() //打印
{
if(!flag)cout<<'-';
while(a[a[0]]==0&&a[0]>1)a[0]--;
cout<<a[a[0]];
for(int i=a[0]-1;i>0;i--)
printf("%04d",a[i]);
}
hac sqrt()
{
hac l,r=*this,m,one;
r.a[0]/=2;
r.a[0]++;
one.store("1");
l.store("0");
if(!flag)return l;//负数无法开方
if(*this==one)return one;
while(l+one<r)
{
m=(l+r).div2();
if(m*m==*this) return m;
(m*m>=*this)? r=m:l=m;
}
return l;
}
};
hac a,b;
string x,y;
int main()
{
cin>>x;
a.store(x);
a.sqrt().print();
return 0;
}