您的位置:首页 > 其它

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

2016-10-18 21:30 204 查看
/*
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;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: