zoukankan      html  css  js  c++  java
  • 【转载】高精度类

    //
    //Search
    //
    //happyZYM 的博客
    //题解 UVA10213 【How Many Pieces of Land ?】
    //
    //2018-05-16 20:09:51thumb_up 0
    //紫书上的思路很容易理解,但时间复杂度太高。在网上搜了半天终于在维基百科上搜到了O(1)算法。 以下证明过程摘自维基百科: pic
    //
    //即答案为 (n*n*n*n-6*n*n*n+23*n*n-18*n+24)/24
    //
    //由于 0≤n≤2^31,需要高精度。
    //
    //c++代码如下:
    #include<iostream>
    #ifndef BIGINT
    #define BIGINT
    #include<vector>
    #include<cstdio>
    #include<string>
    #include<cstring>
    #include<algorithm>
    #include<cmath>
    template<class T_queue>
    struct Node_queue_for_bigint
    {
        T_queue num;
        Node_queue_for_bigint *next;
        Node_queue_for_bigint()
        {
            next=0;
        }
    };
    template<class a_queue>
    struct queue_for_bigint
    {
        Node_queue_for_bigint<a_queue> *head,*tail,*L;
        bool isn;
        int SIZE_queue;
        void beginning()
        {
            head=tail=L=0;
            isn=0;
            head=tail=new Node_queue_for_bigint<a_queue>;
            tail->next=head;
            SIZE_queue=0;
            isn=1;
        }
        queue_for_bigint()
        {
            beginning();
        }
        ~queue_for_bigint()
        {
            Node_queue_for_bigint<a_queue> *p=head,*tp;
            p=p->next;
            while(p!=head)
            {
                tp=p->next;
                delete p;
                p=tp;
            }
        }
        bool push(a_queue s)
        {
            SIZE_queue++;
            tail->num=s;
            if(tail->next==head)
            {
                tail->next=new Node_queue_for_bigint<a_queue>;
                tail->next->next=head;
                L=tail;
                tail=tail->next;
                return 1;
            }
            L=tail;
            tail=tail->next;
            return 0;
        }
        bool pop()
        {
            if(head==tail) return 1;
            head=head->next;
            SIZE_queue--;
            return 0;
        } 
        a_queue& front()
        {
            return head->num;
        } 
        a_queue& back()
        {
            return L->num;
        }
        int size()
        {
            return SIZE_queue;
        }
        void clear()
        {
            SIZE_queue=0;
            tail=head;
        }
        bool operator=(queue_for_bigint<a_queue>b)
        {
            if(!isn)
            {
                this->beginning();
                isn=1;
            }
            this->clear();
            Node_queue_for_bigint<a_queue> *p=b.head;
            while(p!=b.tail)
            {
                this->push(p->num);
                p=p->next;
            }
            return 0;
        }
    };
    int CacheSize=25;//try to use the cache
    queue_for_bigint<char*> Mems;
    queue_for_bigint<int> q;
    queue_for_bigint<char> cache;
    struct BigInt
    {
        char f:4,nAn:4;
        std::vector<int> num;
        static const int base=100000000;
        BigInt()
        {
            f=0;
            nAn=0;
            num.push_back(0);
        }
        template<class TYPE>
        BigInt(TYPE V)
        {
            f=nAn=0;
            *this=V;
        }
        void format()
        {
            while(num.size()>1&&num[num.size()-1]<=0) num.erase(num.end()-1);
            if(num.size()==1&&num[0]==0) f=0;
            if(num.size()==0) num.push_back(0),f=nAn=0;
        }
        //Input and Output
        char* c_str()
        {
            char *p,*ptr;
            if(!nAn)
            {
                p=new char[num.size()*8+16];
                ptr=p;
                memset(p,0,num.size()*8+16);
                if(f) sprintf(p,"-"),p++;
                sprintf(p,"%d",num[num.size()-1]);
                for(int i=num.size()-2;i>=0;i--)
                {
                    while(*p) p++;
                    sprintf(p,"%08d",num[i]);
                }
            }
            else
            {
                p=new char[5];
                sprintf(p,"nan");
            }
            Mems.push(ptr);
            return ptr;
        }
        std::string str()
        {
            std::string ss=c_str();
            return ss;
        }
        BigInt operator=(char* s)
        {
            f=0;
            if(s==0) return BigInt();
            if(*s=='-')
            {
                f=1;
                s++;
            }
            int len=strlen(s),add=0,i,t;
            num.resize(len/8+1);
            char *p=s+len-1;
            while(p-7>=s)
            {
                t=0;
                for(i=-7;i<=0;i++)
                    if(p+i>=s) t=t*10+*(p+i)-'0';
                p-=8;
                num[add++]=t;
            }
            if(p>=s)
            {
                t=0;
                while(s<=p) t=t*10+*(s++)-'0';
                num[add++]=t;
            }
            while(num.size()>add) num.erase(num.end()-1);
            return *this;
        }
        BigInt operator=(std::string ss)
        {
            char *s=&ss[0];
            f=0;
            if(s==0) return BigInt();
            if(*s=='-')
            {
                f=1;
                s++;
            }
            int len=strlen(s),add=0,i,t;
            num.resize(len/8+1);
            char *p=s+len-1;
            while(p>=s)
            {
                t=0;
                for(i=-7;i<=0;i++)
                    if(p+i>=s) t=t*10+*(p+i)-'0';
                p-=8;
                num[add++]=t;
            }
            while(num.size()>add) num.erase(num.end()-1);
            return *this;
        }
        BigInt operator=(int v)
        {
            f=0;
            if(v<0)
            {
                f=1;
                v=-v;
            }
            q.clear();
            if(v==0) q.push(0);
            else
                while(v>0)
                {
                    q.push(v%base);
                    v/=base;
                }
            num.resize(q.size());
            for(int i=0;q.size()>0;i++)
            {
                num[i]=q.front();
                q.pop();
            }
            return *this;
        }
        BigInt operator=(unsigned int v)
        {
            f=0;
            q.clear();
            if(v==0) q.push(0);
            else
                while(v>0)
                {
                    q.push(v%base);
                    v/=base;
                }
            num.resize(q.size());
            for(int i=0;q.size()>0;i++)
            {
                num[i]=q.front();
                q.pop();
            }
            return *this;
        }
        BigInt operator=(long long v)
        {
            f=0;
            if(v<0)
            {
                f=1;
                v=-v;
            }
            q.clear();
            if(v==0) q.push(0);
            else
                while(v>0)
                {
                    q.push(v%base);
                    v/=base;
                }
            num.resize(q.size());
            for(int i=0;q.size()>0;i++)
            {
                num[i]=q.front();
                q.pop();
            }
            return *this;
        }
        BigInt operator=(unsigned long long v)
        {
            f=0;
            q.clear();
            if(v==0) q.push(0);
            else
                while(v>0)
                {
                    q.push(v%base);
                    v/=base;
                }
            num.resize(q.size());
            for(int i=0;q.size()>0;i++)
            {
                num[i]=q.front();
                q.pop();
            }
            return *this;
        }
        //====================/
        //In-situ operation
        BigInt operator++()
        {
            format();
            if(!f)
            {
                num[0]++;
                int i=1;
                while(i<num.size()&&num[i-1]>=base)
                    num[i]++,num[i-1]-=base,i++;
                if(num[i-1]>=base)
                    num.push_back(1),num[i-1]-=base;
            }
            else
            {
                num[0]--;
                int i=1;
                while(i<num.size()&&num[i-1]<0)
                    num[i]--,num[i-1]+=base,i++;
                format();
            }
            return *this;
        }
        BigInt operator++(int)
        {
            format();
            BigInt t=*this;
            if(!f)
            {
                num[0]++;
                int i=1;
                while(i<num.size()&&num[i-1]>=base)
                    num[i]++,num[i-1]-=base,i++;
                if(num[i-1]>=base)
                    num.push_back(1),num[i-1]-=base;
            }
            else
            {
                num[0]--;
                int i=1;
                while(i<num.size()&&num[i-1]<0)
                    num[i]--,num[i-1]+=base,i++;
                format();
            }
            return t;
        }
        BigInt operator--()
        {
            format();
            if(!f)
            {
                num[0]--;
                int i=1;
                while(i<num.size()&&num[i-1]<0)
                    num[i]--,num[i-1]+=base,i++;
                if(num[i-1]<0)
                    *this=-1;
                format();
            }
            else
            {
                num[0]++;
                int i=1;
                while(i<num.size()&&num[i-1]>=base)
                    num[i]++,num[i-1]-=base,i++;
                if(num[i-1]>=base)
                    num.push_back(1),num[i-1]-=base;
            }
            return *this;
        }
        BigInt operator--(int)
        {
            format();
            BigInt t=*this;
            if(!f)
            {
                num[0]--;
                int i=1;
                while(i<num.size()&&num[i-1]<0)
                    num[i]--,num[i-1]+=base,i++;
                if(num[i-1]<0)
                    *this=-1;
                format();
            }
            else
            {
                num[0]++;
                int i=1;
                while(i<num.size()&&num[i-1]>=base)
                    num[i]++,num[i-1]-=base,i++;
                if(num[i-1]>=base)
                    num.push_back(1),num[i-1]-=base;
            }
            return t;
        }
        //=====================/
    };
    //compare operations
    bool operator<(BigInt a,BigInt b)
    {
        a.format();
        b.format();
        if(a.f!=b.f) return a.f>b.f;
        if(a.f==0)
        {
            if(a.num.size()<b.num.size()) return 1;
            else if(a.num.size()>b.num.size()) return 0;
            for(int i=a.num.size()-1;i>=0;i--)
                if(a.num[i]<b.num[i]) return 1;
                else if(a.num[i]>b.num[i]) return 0;
        }
        else
        {
            if(a.num.size()>b.num.size()) return 1;
            else if(a.num.size()<b.num.size()) return 0;
            for(int i=a.num.size()-1;i>=0;i--)
                if(a.num[i]>b.num[i]) return 1;
                else if(a.num[i]<b.num[i]) return 0;
        }
        return 0;
    }
    bool operator==(BigInt a,BigInt b)
    {
        a.format();
        b.format();
        if(a.f!=b.f) return 0;
        if(a.num.size()!=b.num.size()) return 0;
        for(int i=a.num.size()-1;i>=0;i--)
            if(a.num[i]!=b.num[i]) return 0;
        return 1;
    }
    bool operator!=(BigInt a,BigInt b)
    {
        a.format();
        b.format();
        if(a.f!=b.f) return 1;
        if(a.num.size()!=b.num.size()) return 1;
        for(int i=a.num.size()-1;i>=0;i--)
            if(a.num[i]!=b.num[i]) return 1;
        return 0;
    }
    bool operator>(BigInt a,BigInt b)
    {
        a.format();
        b.format();
        if(a.f!=b.f) return a.f<b.f;
        if(a.f==0)
        {
            if(a.num.size()>b.num.size()) return 1;
            else if(a.num.size()<b.num.size()) return 0;
            for(int i=a.num.size()-1;i>=0;i--)
                if(a.num[i]>b.num[i]) return 1;
                else if(a.num[i]<b.num[i]) return 0;
        }
        else
        {
            if(a.num.size()<b.num.size()) return 1;
            else if(a.num.size()>b.num.size()) return 0;
            for(int i=a.num.size()-1;i>=0;i--)
                if(a.num[i]<b.num[i]) return 1;
                else if(a.num[i]>b.num[i]) return 0;
        }
        return 0;
    }
    bool operator<=(const BigInt &a,const BigInt &b){return (a<b||a==b);}
    bool operator>=(const BigInt &a,const BigInt &b){return (a>b||a==b);}
    //=================/
    //maths operations
    BigInt operator+(BigInt a,BigInt b);
    BigInt operator-(BigInt a,BigInt b);
    BigInt operator*(BigInt a,BigInt b);
    BigInt operator/(BigInt a,BigInt b);
    void BigInt_add     (BigInt &a,BigInt &b,BigInt &c);
    void BigInt_minus   (BigInt &a,BigInt &b,BigInt &c);
    void BigInt_times   (BigInt &a,BigInt &b,BigInt &c);
    void BigInt_divide  (BigInt &a,BigInt &b,BigInt &c);
    void BigInt_add(BigInt &a,BigInt &b,BigInt &c)
    {
        a.format();
        b.format();
        c.nAn=(a.nAn==1||b.nAn==1);
        if(c.nAn) return;
        if(a.f)
        {
            if(b.f)
            {
                a.f=b.f=0;
                BigInt_add(a,b,c);
                a.f=b.f=c.f=1;
                return;
            }
            else
            {
                a.f=0;
                BigInt_minus(b,a,c);
                a.f=1;
                return;
            }
        }
        else if(b.f)
        {
            b.f=0;
            BigInt_minus(a,b,c);
            b.f=1;
            return;
        }
        int t=0,t2=std::max(a.num.size(),b.num.size())+1;
        c.num.resize(t2);
        memset(&c.num[0],0,t2*4);
        for(int i=0;i<t2;i++)
        {
            if(i<a.num.size()) t+=a.num[i];
            if(i<b.num.size()) t+=b.num[i];
            c.num[i]=t%BigInt::base;
            t/=BigInt::base;
        }
        c.format();
    }
    void BigInt_minus(BigInt &a,BigInt &b,BigInt &c)
    {
        a.format();
        b.format();
        c.nAn=(a.nAn==1||b.nAn==1);
        if(c.nAn) return;
        if(a.f)
        {
            if(b.f)
            {
                a.f=b.f=0;
                BigInt_minus(b,a,c);
                a.f=b.f=1;
                return;
            }
            else
            {
                a.f=0;
                BigInt_add(a,b,c);
                a.f=c.f=1;
                return;
            }
        }
        else if(b.f)
        {
            b.f=0;
            BigInt_add(a,b,c);
            b.f=1;
            return;
        }
        if(a<b)
        {
            BigInt_minus(b,a,c);
            c.f=1;
            return;
        }
        c=a;
        int z=0,k;
        for(int i=0;i<b.num.size();i++)
        {
            c.num[i]=c.num[i]-b.num[i];
            if(c.num[i]<0)
            {
                c.num[i]+=BigInt::base;
                z=1;
            }
            else z=0;
            k=i+1;
            while(z&&k<c.num.size())
            {
                c.num[k]--;
                if(c.num[k]<0)
                {
                    z=1;
                    c.num[k]+BigInt::base;
                }
                else z=0;
                k++;
            }
        }
        c.format();
    }
    void BigInt_times(BigInt &a,BigInt &b,BigInt &c)
    {
        a.format();
        b.format();
        c.nAn=(a.nAn==1||b.nAn==1);
        if(c.nAn) return;
        c.num.resize(a.num.size()+b.num.size());
        memset(&c.num[0],0,(a.num.size()+b.num.size())*4);
        int i,j,k,I,J;
        long long t;
        int *A,*B,*C,As=a.num.size(),Bs=b.num.size();
        A=&(a.num[0]);
        B=&(b.num[0]);
        C=&(c.num[0]);
        for(i=0;i<As;i+=CacheSize)
            for(j=0;j<Bs;j+=CacheSize)
                for(I=i;I<i+CacheSize&&I<As;I++)
                    for(J=j;J<j+CacheSize&&J<Bs;J++)
                    {
                        t=(long long)A[I]*B[J];
                        t=t+C[I+J];
                        C[I+J]=t%BigInt::base;
                        k=I+J+1;
                        t/=BigInt::base;
                        while(t>0)
                        {
                            t=t+C[k];
                            C[k++]=t%BigInt::base;
                            t=t/BigInt::base;
                        }
                    }
        c.f=(a.f!=b.f);
        c.format();
    }
    void BigInt_divide(BigInt &a,BigInt &b,BigInt &c)
    {
        BigInt t;
        a.format();
        b.format();
        bool af=a.f,bf=b.f;
        a.f=b.f=0;
        if(a<b)
        {
            c=BigInt();
            return;
        }
        c.nAn=(a.nAn==1||b.nAn==1||(b.num.size()==1&&b.num[0]==0));
        c.f=0;
        if(c.nAn) return;
        c.num.resize(a.num.size()-b.num.size()+1,0);
        int L,R;
        for(int i=c.num.size()-1;i>=0;i--)
        {
            L=0;
            R=a.base-1;
            while(L+1<R)
            {
                c.num[i]=(L+R)/2;
                BigInt_times(b,c,t);
                if(t>a) R=(L+R)/2;
                else L=(L+R)/2;
            }
            c.num[i]=L;
        }
        c.format();
        a.f=af;
        b.f=bf;
        c.f=(af!=bf);
    }
    BigInt operator+(BigInt a,BigInt b)
    {
        BigInt t;
        BigInt_add(a,b,t);
        return t;
    }
    BigInt operator+=(BigInt &a,BigInt b)
    {
        BigInt t;
        BigInt_add(a,b,t);
        return a=t;
    }
    BigInt operator-(BigInt a,BigInt b)
    {
        BigInt t;
        BigInt_minus(a,b,t);
        return t;
    }
    BigInt operator-=(BigInt &a,BigInt b)
    {
        BigInt t;
        BigInt_minus(a,b,t);
        return a=t;
    }
    BigInt operator*(BigInt a,BigInt b)
    {
        BigInt t;
        BigInt_times(a,b,t);
        return t;
    }
    BigInt operator*=(BigInt &a,BigInt b)
    {
        BigInt t;
        BigInt_times(a,b,t);
        return a=t;
    }
    BigInt operator/(BigInt a,BigInt b)
    {
        BigInt c;
        BigInt_divide(a,b,c);
        return c;
    }
    BigInt operator/=(BigInt &a,BigInt b)
    {
        BigInt c;
        BigInt_divide(a,b,c);
        return a=c;
    }
    BigInt operator%(BigInt a,BigInt b)
    {
        BigInt t1,t2;
        BigInt_divide(a,b,t1);
        BigInt_times(t1,b,t2);
        BigInt_minus(a,t2,t1);
        return t1;
    }
    BigInt operator%=(BigInt &a,BigInt b)
    {
        BigInt t1,t2;
        BigInt_divide(a,b,t1);
        BigInt_times(t1,b,t2);
        BigInt_minus(a,t2,t1);
        return a=t1;
    }
    void free_pointers()//Releasing temporary memory
    {
        while(Mems.size()>0)
        {
            delete[] Mems.front();
            Mems.pop();
        }
    }
    //======================/
    #endif
    
    //stream input and output
    #ifdef _GLIBCXX_OSTREAM
    std::ostream& operator<<(std::ostream& str,BigInt n)
    {
        n.format();
        if(n.nAn) str<<"nan";
        else
            str<<n.c_str();
        return str;
    }
    #endif
    
    #ifdef _GLIBCXX_ISTREAM
    std::istream& operator>>(std::istream& str,BigInt &n)
    {
        cache.clear();
        while(!str.eof()&&!(str.peek()=='-'||(str.peek()>='0'&&str.peek()<='9')))
            str.get();
        bool flag=0;
        while(!str.eof()&&str.peek()=='-') flag=!flag,str.get();
        if(flag) cache.push('-');
        while(!str.eof()&&str.peek()>='0'&&str.peek()<='9') cache.push(str.get());
        char *p=new char[cache.size()+1],*t;
        memset(p,0,cache.size()+1);
        t=p;
        while(cache.size()>0) *t++=cache.front(),cache.pop();
        n=p;
        delete[] p;
        return str;
    }
    #endif//以上的高精度代码摘自我自己编写的一个高精度库。
    using namespace std;
    int T;
    BigInt n,res;//定义大型整数类; 
    int main()
    {
    #ifdef local
        //freopen("pro.in","r",stdin);
    #endif
    //    cin>>T;
    //    while(T-->0)
    //    {
    //        cin>>n;
    //        res=(n*(n*(n*(n-6)+23)-18)+24)/24;
    //        /*
    //        优化计算,原式为
    //        (n*n*n*n-6*n*n*n+23*n*n-18*n+24)/24
    //        */
    //        cout<<res<<endl;
    //    }
         cin>>n>>res;
         res=n;
         cout<<res;
        return 0;
    }
  • 相关阅读:
    【shell】 for循环
    【shell】case语句
    【shell】if语句
    【shell】nmap工具的使用
    spring3 循环依赖
    spring3 DI基础
    spring3系列一
    正则表达式学习网址
    常用正则表达式
    hibernate延迟加载
  • 原文地址:https://www.cnblogs.com/ltlt/p/9118921.html
Copyright © 2011-2022 走看看