codevs 3119 高精度练习之大整数开根 (各种高精+压位)

时间:2021-10-03 17:45:02
/*
codevs 3119 高精度练习之大整数开根 (各种高精+压位)
二分答案 然后高精判重 打了一个多小时.....
最后还超时了...压位就好了
测试点#1.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms
测试点#2.in 结果:AC 内存使用量: 256kB 时间使用量: 1ms
测试点#3.in 结果:AC 内存使用量: 256kB 时间使用量: 0ms
测试点#4.in 结果:AC 内存使用量: 256kB 时间使用量: 10ms
测试点#5.in 结果:AC 内存使用量: 256kB 时间使用量: 56ms
*/
#include<cstdio>
#include<cstring>
#include<cmath>
#define maxn 1010
#define ll long long
#define bas 100000000
#define mem(a,b) for(ll i=0;i<=len;i++)a[i]=b[i];
#define mes(a) for(ll i=0;i<=len;i++)a[i]=0;
using namespace std;
ll len,a[maxn],l[maxn],r[maxn],mid[maxn],ans[maxn],x[maxn];
char s[maxn];
ll max(ll x,ll y){
return x>y?x:y;
}
void plu(ll a[maxn],ll b[maxn]){
ll c[maxn];mes(c);
c[]=max(a[],b[]);
for(int i=;i<=c[];i++){
c[i]+=a[i]+b[i];
if(c[i]>=bas){
c[i+]++;c[i]%=bas;
}
}
if(c[c[]+])c[]++;
mem(mid,c);
}
void Plu(ll a[maxn],ll b){
ll p=,c[maxn];mes(c);
mem(c,a);c[p]++;
while(c[p]>=bas){
c[p]%=bas;c[p+]++;p++;
}
if(c[c[]+])c[]++;
mem(l,c);
}
void miu(ll a[maxn],ll b){
ll p=,c[maxn];mes(c);
mem(c,a);c[p]--;
while(c[p]<){
c[p]+=bas;c[p+]--;p++;
}
if(c[c[]]==)c[]--;
mem(r,c);
}
void mul(ll a[maxn],ll b[maxn],ll c[maxn]){
for(int i=;i<=a[];i++){
for(int j=;j<=b[];j++){
c[i+j-]+=a[i]*b[j];
if(c[i+j-]>=bas){
c[i+j]+=c[i+j-]/bas;
c[i+j-]%=bas;
}
}
ll len=i+b[];
while(c[len]>=bas){
c[len+]+=c[len]/bas;
c[len]%=bas;len++;
}
}
for(int i=a[]+b[];i>=;i--)
if(c[i]){
c[]=i;break;
}
}
void div(ll a[maxn],ll b){
ll c[maxn];mes(c);
for(int i=a[];i>=;i--){
c[i]=a[i+]%b*bas+a[i];
c[i]=c[i]/b;
}
for(int i=a[];i>=;i--)
if(c[i]){
c[]=i;break;
}
mem(a,c);
}
bool cmp(ll a[maxn],ll b[maxn]){
if(a[]>b[])return ;
if(a[]<b[])return ;
for(ll i=a[];i>=;i--){
if(a[i]>b[i])return ;
if(a[i]<b[i])return ;
}
return ;
}
bool Judge(){
memset(x,,sizeof(x));
mul(mid,mid,x);
return cmp(x,a);
}
int main()
{
scanf("%s",s);
a[]=strlen(s);len=a[];
for(int i=;i<=a[];i++)
a[i]=s[a[]-i]-'';
for(int i=;i<=len;i+=)
x[++x[]]=a[i+]*+a[i+]*+a[i+]*+
a[i+]*+a[i+]*+a[i+]*+a[i+]*+a[i];
mem(a,x);
mem(r,a);r[]=a[]/+;
while(cmp(l,r)){
plu(l,r);
div(mid,);
if(Judge()){
mem(ans,mid);
Plu(mid,);
}
else miu(mid,);
}
printf("%lld",ans[ans[]]);
for(ll i=ans[]-;i>=;i--)
printf("%08lld",ans[i]);
return ;
}