zoukankan      html  css  js  c++  java
  • 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;
    }
  • 相关阅读:
    A1023 Have Fun with Numbers (20分)(大整数四则运算)
    A1096 Consecutive Factors (20分)(质数分解)
    A1078 Hashing (25分)(哈希表、平方探测法)
    A1015 Reversible Primes (20分)(素数判断,进制转换)
    A1081 Rational Sum (20分)
    A1088 Rational Arithmetic (20分)
    A1049 Counting Ones (30分)
    A1008 Elevator (20分)
    A1059 Prime Factors (25分)
    A1155 Heap Paths (30分)
  • 原文地址:https://www.cnblogs.com/yanlifneg/p/5975101.html
Copyright © 2011-2022 走看看