首页 > 代码库 > codevs 3119 高精度练习之大整数开根 (各种高精+压位)
codevs 3119 高精度练习之大整数开根 (各种高精+压位)
/*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[0]=max(a[0],b[0]); for(int i=1;i<=c[0];i++){ c[i]+=a[i]+b[i]; if(c[i]>=bas){ c[i+1]++;c[i]%=bas; } } if(c[c[0]+1])c[0]++; mem(mid,c);}void Plu(ll a[maxn],ll b){ ll p=1,c[maxn];mes(c); mem(c,a);c[p]++; while(c[p]>=bas){ c[p]%=bas;c[p+1]++;p++; } if(c[c[0]+1])c[0]++; mem(l,c);}void miu(ll a[maxn],ll b){ ll p=1,c[maxn];mes(c); mem(c,a);c[p]--; while(c[p]<0){ c[p]+=bas;c[p+1]--;p++; } if(c[c[0]]==0)c[0]--; mem(r,c);}void mul(ll a[maxn],ll b[maxn],ll c[maxn]){ for(int i=1;i<=a[0];i++){ for(int j=1;j<=b[0];j++){ c[i+j-1]+=a[i]*b[j]; if(c[i+j-1]>=bas){ c[i+j]+=c[i+j-1]/bas; c[i+j-1]%=bas; } } ll len=i+b[0]; while(c[len]>=bas){ c[len+1]+=c[len]/bas; c[len]%=bas;len++; } } for(int i=a[0]+b[0];i>=1;i--) if(c[i]){ c[0]=i;break; }}void div(ll a[maxn],ll b){ ll c[maxn];mes(c); for(int i=a[0];i>=1;i--){ c[i]=a[i+1]%b*bas+a[i]; c[i]=c[i]/b; } for(int i=a[0];i>=1;i--) if(c[i]){ c[0]=i;break; } mem(a,c);}bool cmp(ll a[maxn],ll b[maxn]){ if(a[0]>b[0])return 0; if(a[0]<b[0])return 1; for(ll i=a[0];i>=1;i--){ if(a[i]>b[i])return 0; if(a[i]<b[i])return 1; } return 1;}bool Judge(){ memset(x,0,sizeof(x)); mul(mid,mid,x); return cmp(x,a);}int main(){ scanf("%s",s); a[0]=strlen(s);len=a[0]; for(int i=1;i<=a[0];i++) a[i]=s[a[0]-i]-‘0‘; for(int i=1;i<=len;i+=8) x[++x[0]]=a[i+7]*10000000+a[i+6]*1000000+a[i+5]*100000+ a[i+4]*10000+a[i+3]*1000+a[i+2]*100+a[i+1]*10+a[i]; mem(a,x); mem(r,a);r[0]=a[0]/2+1; while(cmp(l,r)){ plu(l,r); div(mid,2); if(Judge()){ mem(ans,mid); Plu(mid,1); } else miu(mid,1); } printf("%lld",ans[ans[0]]); for(ll i=ans[0]-1;i>=1;i--) printf("%08lld",ans[i]); return 0;}
codevs 3119 高精度练习之大整数开根 (各种高精+压位)
声明:以上内容来自用户投稿及互联网公开渠道收集整理发布,本网站不拥有所有权,未作人工编辑处理,也不承担相关法律责任,若内容有误或涉及侵权可进行投诉: 投诉/举报 工作人员会在5个工作日内联系你,一经查实,本站将立刻删除涉嫌侵权内容。