【UVA】10213 - How Many Pieces of Land ?(大树模板X2)

从网上COPY下来的2个模板:

The First:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;

#include <iostream>
#include <cstring>
using namespace std;

#define DIGIT   4      //四位隔开,即万进制
#define DEPTH   10000        //万进制
#define MAX     10000    //题目最大位数/4,要不大直接设为最大位数也行
typedef int bignum_t[MAX+1];

/************************************************************************/
/* 读取操作数,对操作数进行处理存储在数组里                             */
/************************************************************************/
int read(bignum_t a,istream&is=cin)
{
    char buf[MAX*DIGIT+1],ch ;
    int i,j ;
    memset((void*)a,0,sizeof(bignum_t));
    if(!(is>>buf))return 0 ;
    for(a[0]=strlen(buf),i=a[0]/2-1; i>=0; i--)
        ch=buf[i],buf[i]=buf[a[0]-1-i],buf[a[0]-1-i]=ch ;
    for(a[0]=(a[0]+DIGIT-1)/DIGIT,j=strlen(buf); j<a[0]*DIGIT; buf[j++]='0');
    for(i=1; i<=a[0]; i++)
        for(a[i]=0,j=0; j<DIGIT; j++)
            a[i]=a[i]*10+buf[i*DIGIT-1-j]-'0' ;
    for(; !a[a[0]]&&a[0]>1; a[0]--);
    return 1 ;
}

void write(const bignum_t a,ostream&os=cout)
{
    int i,j ;
    for(os<<a[i=a[0]],i--; i; i--)
        for(j=DEPTH/10; j; j/=10)
            os<<a[i]/j%10 ;
}

int comp(const bignum_t a,const bignum_t b)
{
    int i ;
    if(a[0]!=b[0])
        return a[0]-b[0];
    for(i=a[0]; i; i--)
        if(a[i]!=b[i])
            return a[i]-b[i];
    return 0 ;
}

int comp(const bignum_t a,const int b)
{
    int c[12]=
    {
        1
    }
    ;
    for(c[1]=b; c[c[0]]>=DEPTH; c[c[0]+1]=c[c[0]]/DEPTH,c[c[0]]%=DEPTH,c[0]++);
    return comp(a,c);
}

int comp(const bignum_t a,const int c,const int d,const bignum_t b)
{
    int i,t=0,O=-DEPTH*2 ;
    if(b[0]-a[0]<d&&c)
        return 1 ;
    for(i=b[0]; i>d; i--)
    {
        t=t*DEPTH+a[i-d]*c-b[i];
        if(t>0)return 1 ;
        if(t<O)return 0 ;
    }
    for(i=d; i; i--)
    {
        t=t*DEPTH-b[i];
        if(t>0)return 1 ;
        if(t<O)return 0 ;
    }
    return t>0 ;
}
/************************************************************************/
/* 大数与大数相加                                                       */
/************************************************************************/
void add(bignum_t a,const bignum_t b)
{
    int i ;
    for(i=1; i<=b[0]; i++)
        if((a[i]+=b[i])>=DEPTH)
            a[i]-=DEPTH,a[i+1]++;
    if(b[0]>=a[0])
        a[0]=b[0];
    else
        for(; a[i]>=DEPTH&&i<a[0]; a[i]-=DEPTH,i++,a[i]++);
    a[0]+=(a[a[0]+1]>0);
}
/************************************************************************/
/* 大数与小数相加                                                       */
/************************************************************************/
void add(bignum_t a,const int b)
{
    int i=1 ;
    for(a[1]+=b; a[i]>=DEPTH&&i<a[0]; a[i+1]+=a[i]/DEPTH,a[i]%=DEPTH,i++);
    for(; a[a[0]]>=DEPTH; a[a[0]+1]=a[a[0]]/DEPTH,a[a[0]]%=DEPTH,a[0]++);
}
/************************************************************************/
/* 大数相减(被减数>=减数)                                               */
/************************************************************************/
void sub(bignum_t a,const bignum_t b)
{
    int i ;
    for(i=1; i<=b[0]; i++)
        if((a[i]-=b[i])<0)
            a[i+1]--,a[i]+=DEPTH ;
    for(; a[i]<0; a[i]+=DEPTH,i++,a[i]--);
    for(; !a[a[0]]&&a[0]>1; a[0]--);
}
/************************************************************************/
/* 大数减去小数(被减数>=减数)                                           */
/************************************************************************/
void sub(bignum_t a,const int b)
{
    int i=1 ;
    for(a[1]-=b; a[i]<0; a[i+1]+=(a[i]-DEPTH+1)/DEPTH,a[i]-=(a[i]-DEPTH+1)/DEPTH*DEPTH,i++);
    for(; !a[a[0]]&&a[0]>1; a[0]--);
}

void sub(bignum_t a,const bignum_t b,const int c,const int d)
{
    int i,O=b[0]+d ;
    for(i=1+d; i<=O; i++)
        if((a[i]-=b[i-d]*c)<0)
            a[i+1]+=(a[i]-DEPTH+1)/DEPTH,a[i]-=(a[i]-DEPTH+1)/DEPTH*DEPTH ;
    for(; a[i]<0; a[i+1]+=(a[i]-DEPTH+1)/DEPTH,a[i]-=(a[i]-DEPTH+1)/DEPTH*DEPTH,i++);
    for(; !a[a[0]]&&a[0]>1; a[0]--);
}
/************************************************************************/
/* 大数相乘,读入被乘数a,乘数b,结果保存在c[]                          */
/************************************************************************/
void mul(bignum_t c,const bignum_t a,const bignum_t b)
{
    int i,j ;
    memset((void*)c,0,sizeof(bignum_t));
    for(c[0]=a[0]+b[0]-1,i=1; i<=a[0]; i++)
        for(j=1; j<=b[0]; j++)
            if((c[i+j-1]+=a[i]*b[j])>=DEPTH)
                c[i+j]+=c[i+j-1]/DEPTH,c[i+j-1]%=DEPTH ;
    for(c[0]+=(c[c[0]+1]>0); !c[c[0]]&&c[0]>1; c[0]--);
}
/************************************************************************/
/* 大数乘以小数,读入被乘数a,乘数b,结果保存在被乘数                   */
/************************************************************************/
void mul(bignum_t a,const int b)
{
    int i ;
    for(a[1]*=b,i=2; i<=a[0]; i++)
    {
        a[i]*=b ;
        if(a[i-1]>=DEPTH)
            a[i]+=a[i-1]/DEPTH,a[i-1]%=DEPTH ;
    }
    for(; a[a[0]]>=DEPTH; a[a[0]+1]=a[a[0]]/DEPTH,a[a[0]]%=DEPTH,a[0]++);
    for(; !a[a[0]]&&a[0]>1; a[0]--);
}

void mul(bignum_t b,const bignum_t a,const int c,const int d)
{
    int i ;
    memset((void*)b,0,sizeof(bignum_t));
    for(b[0]=a[0]+d,i=d+1; i<=b[0]; i++)
        if((b[i]+=a[i-d]*c)>=DEPTH)
            b[i+1]+=b[i]/DEPTH,b[i]%=DEPTH ;
    for(; b[b[0]+1]; b[0]++,b[b[0]+1]=b[b[0]]/DEPTH,b[b[0]]%=DEPTH);
    for(; !b[b[0]]&&b[0]>1; b[0]--);
}
/**************************************************************************/
/* 大数相除,读入被除数a,除数b,结果保存在c[]数组                         */
/* 需要comp()函数                                                         */
/**************************************************************************/
void div(bignum_t c,bignum_t a,const bignum_t b)
{
    int h,l,m,i ;
    memset((void*)c,0,sizeof(bignum_t));
    c[0]=(b[0]<a[0]+1)?(a[0]-b[0]+2):1 ;
    for(i=c[0]; i; sub(a,b,c[i]=m,i-1),i--)
        for(h=DEPTH-1,l=0,m=(h+l+1)>>1; h>l; m=(h+l+1)>>1)
            if(comp(b,m,i-1,a))h=m-1 ;
            else l=m ;
    for(; !c[c[0]]&&c[0]>1; c[0]--);
    c[0]=c[0]>1?c[0]:1 ;
}

void div(bignum_t a,const int b,int&c)
{
    int i ;
    for(c=0,i=a[0]; i; c=c*DEPTH+a[i],a[i]=c/b,c%=b,i--);
    for(; !a[a[0]]&&a[0]>1; a[0]--);
}
/************************************************************************/
/* 大数平方根,读入大数a,结果保存在b[]数组里                           */
/* 需要comp()函数                                                       */
/************************************************************************/
void sqrt(bignum_t b,bignum_t a)
{
    int h,l,m,i ;
    memset((void*)b,0,sizeof(bignum_t));
    for(i=b[0]=(a[0]+1)>>1; i; sub(a,b,m,i-1),b[i]+=m,i--)
        for(h=DEPTH-1,l=0,b[i]=m=(h+l+1)>>1; h>l; b[i]=m=(h+l+1)>>1)
            if(comp(b,m,i-1,a))h=m-1 ;
            else l=m ;
    for(; !b[b[0]]&&b[0]>1; b[0]--);
    for(i=1; i<=b[0]; b[i++]>>=1);
}
/************************************************************************/
/* 返回大数的长度                                                       */
/************************************************************************/
int length(const bignum_t a)
{
    int t,ret ;
    for(ret=(a[0]-1)*DIGIT,t=a[a[0]]; t; t/=10,ret++);
    return ret>0?ret:1 ;
}
/************************************************************************/
/* 返回指定位置的数字,从低位开始数到第b位,返回b位上的数               */
/************************************************************************/
int digit(const bignum_t a,const int b)
{
    int i,ret ;
    for(ret=a[(b-1)/DIGIT+1],i=(b-1)%DIGIT; i; ret/=10,i--);
    return ret%10 ;
}
/************************************************************************/
/* 返回大数末尾0的个数                                                  */
/************************************************************************/
int zeronum(const bignum_t a)
{
    int ret,t ;
    for(ret=0; !a[ret+1]; ret++);
    for(t=a[ret+1],ret*=DIGIT; !(t%10); t/=10,ret++);
    return ret ;
}

void comp(int*a,const int l,const int h,const int d)
{
    int i,j,t ;
    for(i=l; i<=h; i++)
        for(t=i,j=2; t>1; j++)
            while(!(t%j))
                a[j]+=d,t/=j ;
}

void convert(int*a,const int h,bignum_t b)
{
    int i,j,t=1 ;
    memset(b,0,sizeof(bignum_t));
    for(b[0]=b[1]=1,i=2; i<=h; i++)
        if(a[i])
            for(j=a[i]; j; t*=i,j--)
                if(t*i>DEPTH)
                    mul(b,t),t=1 ;
    mul(b,t);
}
/************************************************************************/
/* 组合数                                                               */
/************************************************************************/
void combination(bignum_t a,int m,int n)
{
    int*t=new int[m+1];
    memset((void*)t,0,sizeof(int)*(m+1));
    comp(t,n+1,m,1);
    comp(t,2,m-n,-1);
    convert(t,m,a);
    delete[]t ;
}
/************************************************************************/
/* 排列数                                                               */
/************************************************************************/
void permutation(bignum_t a,int m,int n)
{
    int i,t=1 ;
    memset(a,0,sizeof(bignum_t));
    a[0]=a[1]=1 ;
    for(i=m-n+1; i<=m; t*=i++)
        if(t*i>DEPTH)
            mul(a,t),t=1 ;
    mul(a,t);
}

#define SGN(x) ((x)>0?1:((x)<0?-1:0))
#define ABS(x) ((x)>0?(x):-(x))

int read(bignum_t a,int&sgn,istream&is=cin)
{
    char str[MAX*DIGIT+2],ch,*buf ;
    int i,j ;
    memset((void*)a,0,sizeof(bignum_t));
    if(!(is>>str))return 0 ;
    buf=str,sgn=1 ;
    if(*buf=='-')sgn=-1,buf++;
    for(a[0]=strlen(buf),i=a[0]/2-1; i>=0; i--)
        ch=buf[i],buf[i]=buf[a[0]-1-i],buf[a[0]-1-i]=ch ;
    for(a[0]=(a[0]+DIGIT-1)/DIGIT,j=strlen(buf); j<a[0]*DIGIT; buf[j++]='0');
    for(i=1; i<=a[0]; i++)
        for(a[i]=0,j=0; j<DIGIT; j++)
            a[i]=a[i]*10+buf[i*DIGIT-1-j]-'0' ;
    for(; !a[a[0]]&&a[0]>1; a[0]--);
    if(a[0]==1&&!a[1])sgn=0 ;
    return 1 ;
}
struct bignum
{
    bignum_t num ;
    int sgn ;
public :
    inline bignum()
    {
        memset(num,0,sizeof(bignum_t));
        num[0]=1 ;
        sgn=0 ;
    }
    inline int operator!()
    {
        return num[0]==1&&!num[1];
    }
    inline bignum&operator=(const bignum&a)
    {
        memcpy(num,a.num,sizeof(bignum_t));
        sgn=a.sgn ;
        return*this ;
    }
    inline bignum&operator=(const int a)
    {
        memset(num,0,sizeof(bignum_t));
        num[0]=1 ;
        sgn=SGN (a);
        add(num,sgn*a);
        return*this ;
    }
    ;
    inline bignum&operator+=(const bignum&a)
    {
        if(sgn==a.sgn)add(num,a.num);
        else if
        (sgn&&a.sgn)
        {
            int ret=comp(num,a.num);
            if(ret>0)sub(num,a.num);
            else if(ret<0)
            {
                bignum_t t ;
                memcpy(t,num,sizeof(bignum_t));
                memcpy(num,a.num,sizeof(bignum_t));
                sub (num,t);
                sgn=a.sgn ;
            }
            else memset(num,0,sizeof(bignum_t)),num[0]=1,sgn=0 ;
        }
        else if(!sgn)
            memcpy(num,a.num,sizeof(bignum_t)),sgn=a.sgn ;
        return*this ;
    }
    inline bignum&operator+=(const int a)
    {
        if(sgn*a>0)add(num,ABS(a));
        else if(sgn&&a)
        {
            int  ret=comp(num,ABS(a));
            if(ret>0)sub(num,ABS(a));
            else if(ret<0)
            {
                bignum_t t ;
                memcpy(t,num,sizeof(bignum_t));
                memset(num,0,sizeof(bignum_t));
                num[0]=1 ;
                add(num,ABS (a));
                sgn=-sgn ;
                sub(num,t);
            }
            else memset(num,0,sizeof(bignum_t)),num[0]=1,sgn=0 ;
        }
        else if
        (!sgn)sgn=SGN(a),add(num,ABS(a));
        return*this ;
    }
    inline bignum operator+(const bignum&a)
    {
        bignum ret ;
        memcpy(ret.num,num,sizeof (bignum_t));
        ret.sgn=sgn ;
        ret+=a ;
        return ret ;
    }
    inline bignum operator+(const int a)
    {
        bignum ret ;
        memcpy(ret.num,num,sizeof (bignum_t));
        ret.sgn=sgn ;
        ret+=a ;
        return ret ;
    }
    inline bignum&operator-=(const bignum&a)
    {
        if(sgn*a.sgn<0)add(num,a.num);
        else if
        (sgn&&a.sgn)
        {
            int ret=comp(num,a.num);
            if(ret>0)sub(num,a.num);
            else if(ret<0)
            {
                bignum_t t ;
                memcpy(t,num,sizeof(bignum_t));
                memcpy(num,a.num,sizeof(bignum_t));
                sub(num,t);
                sgn=-sgn ;
            }
            else memset(num,0,sizeof(bignum_t)),num[0]=1,sgn=0 ;
        }
        else if(!sgn)add (num,a.num),sgn=-a.sgn ;
        return*this ;
    }
    inline bignum&operator-=(const int a)
    {
        if(sgn*a<0)add(num,ABS(a));
        else if(sgn&&a)
        {
            int  ret=comp(num,ABS(a));
            if(ret>0)sub(num,ABS(a));
            else if(ret<0)
            {
                bignum_t t ;
                memcpy(t,num,sizeof(bignum_t));
                memset(num,0,sizeof(bignum_t));
                num[0]=1 ;
                add(num,ABS(a));
                sub(num,t);
                sgn=-sgn ;
            }
            else memset(num,0,sizeof(bignum_t)),num[0]=1,sgn=0 ;
        }
        else if
        (!sgn)sgn=-SGN(a),add(num,ABS(a));
        return*this ;
    }
    inline bignum operator-(const bignum&a)
    {
        bignum ret ;
        memcpy(ret.num,num,sizeof(bignum_t));
        ret.sgn=sgn ;
        ret-=a ;
        return ret ;
    }
    inline bignum operator-(const int a)
    {
        bignum ret ;
        memcpy(ret.num,num,sizeof(bignum_t));
        ret.sgn=sgn ;
        ret-=a ;
        return ret ;
    }
    inline bignum&operator*=(const bignum&a)
    {
        bignum_t t ;
        mul(t,num,a.num);
        memcpy(num,t,sizeof(bignum_t));
        sgn*=a.sgn ;
        return*this ;
    }
    inline bignum&operator*=(const int a)
    {
        mul(num,ABS(a));
        sgn*=SGN(a);
        return*this ;
    }
    inline bignum operator*(const bignum&a)
    {
        bignum ret ;
        mul(ret.num,num,a.num);
        ret.sgn=sgn*a.sgn ;
        return ret ;
    }
    inline bignum operator*(const int a)
    {
        bignum ret ;
        memcpy(ret.num,num,sizeof (bignum_t));
        mul(ret.num,ABS(a));
        ret.sgn=sgn*SGN(a);
        return ret ;
    }
    inline bignum&operator/=(const bignum&a)
    {
        bignum_t t ;
        div(t,num,a.num);
        memcpy (num,t,sizeof(bignum_t));
        sgn=(num[0]==1&&!num[1])?0:sgn*a.sgn ;
        return*this ;
    }
    inline bignum&operator/=(const int a)
    {
        int t ;
        div(num,ABS(a),t);
        sgn=(num[0]==1&&!num [1])?0:sgn*SGN(a);
        return*this ;
    }
    inline bignum operator/(const bignum&a)
    {
        bignum ret ;
        bignum_t t ;
        memcpy(t,num,sizeof(bignum_t));
        div(ret.num,t,a.num);
        ret.sgn=(ret.num[0]==1&&!ret.num[1])?0:sgn*a.sgn ;
        return ret ;
    }
    inline bignum operator/(const int a)
    {
        bignum ret ;
        int t ;
        memcpy(ret.num,num,sizeof(bignum_t));
        div(ret.num,ABS(a),t);
        ret.sgn=(ret.num[0]==1&&!ret.num[1])?0:sgn*SGN(a);
        return ret ;
    }
    inline bignum&operator%=(const bignum&a)
    {
        bignum_t t ;
        div(t,num,a.num);
        if(num[0]==1&&!num[1])sgn=0 ;
        return*this ;
    }
    inline int operator%=(const int a)
    {
        int t ;
        div(num,ABS(a),t);
        memset(num,0,sizeof (bignum_t));
        num[0]=1 ;
        add(num,t);
        return t ;
    }
    inline bignum operator%(const bignum&a)
    {
        bignum ret ;
        bignum_t t ;
        memcpy(ret.num,num,sizeof(bignum_t));
        div(t,ret.num,a.num);
        ret.sgn=(ret.num[0]==1&&!ret.num [1])?0:sgn ;
        return ret ;
    }
    inline int operator%(const int a)
    {
        bignum ret ;
        int t ;
        memcpy(ret.num,num,sizeof(bignum_t));
        div(ret.num,ABS(a),t);
        memset(ret.num,0,sizeof(bignum_t));
        ret.num[0]=1 ;
        add(ret.num,t);
        return t ;
    }
    inline bignum&operator++()
    {
        *this+=1 ;
        return*this ;
    }
    inline bignum&operator--()
    {
        *this-=1 ;
        return*this ;
    }
    ;
    inline int operator>(const bignum&a)
    {
        return sgn>0?(a.sgn>0?comp(num,a.num)>0:1):(sgn<0?(a.sgn<0?comp(num,a.num)<0:0):a.sgn<0);
    }
    inline int operator>(const int a)
    {
        return sgn>0?(a>0?comp(num,a)>0:1):(sgn<0?(a<0?comp(num,-a)<0:0):a<0);
    }
    inline int operator>=(const bignum&a)
    {
        return sgn>0?(a.sgn>0?comp(num,a.num)>=0:1):(sgn<0?(a.sgn<0?comp(num,a.num)<=0:0):a.sgn<=0);
    }
    inline int operator>=(const int a)
    {
        return sgn>0?(a>0?comp(num,a)>=0:1):(sgn<0?(a<0?comp(num,-a)<=0:0):a<=0);
    }
    inline int operator<(const bignum&a)
    {
        return sgn<0?(a.sgn<0?comp(num,a.num)>0:1):(sgn>0?(a.sgn>0?comp(num,a.num)<0:0):a.sgn>0);
    }
    inline int operator<(const int a)
    {
        return sgn<0?(a<0?comp(num,-a)>0:1):(sgn>0?(a>0?comp(num,a)<0:0):a>0);
    }
    inline int operator<=(const bignum&a)
    {
        return sgn<0?(a.sgn<0?comp(num,a.num)>=0:1):(sgn>0?(a.sgn>0?comp(num,a.num)<=0:0):a.sgn>=0);
    }
    inline int operator<=(const int a)
    {
        return sgn<0?(a<0?comp(num,-a)>=0:1):
               (sgn>0?(a>0?comp(num,a)<=0:0):a>=0);
    }
    inline int operator==(const bignum&a)
    {
        return(sgn==a.sgn)?!comp(num,a.num):0 ;
    }
    inline int operator==(const int a)
    {
        return(sgn*a>=0)?!comp(num,ABS(a)):0 ;
    }
    inline int operator!=(const bignum&a)
    {
        return(sgn==a.sgn)?comp(num,a.num):1 ;
    }
    inline int operator!=(const int a)
    {
        return(sgn*a>=0)?comp(num,ABS(a)):1 ;
    }
    inline int operator[](const int a)
    {
        return digit(num,a);
    }
    friend inline istream&operator>>(istream&is,bignum&a)
    {
        read(a.num,a.sgn,is);
        return  is ;
    }
    friend inline ostream&operator<<(ostream&os,const bignum&a)
    {
        if(a.sgn<0)
            os<<'-' ;
        write(a.num,os);
        return os ;
    }
    friend inline bignum sqrt(const bignum&a)
    {
        bignum ret ;
        bignum_t t ;
        memcpy(t,a.num,sizeof(bignum_t));
        sqrt(ret.num,t);
        ret.sgn=ret.num[0]!=1||ret.num[1];
        return ret ;
    }
    friend inline bignum sqrt(const bignum&a,bignum&b)
    {
        bignum ret ;
        memcpy(b.num,a.num,sizeof(bignum_t));
        sqrt(ret.num,b.num);
        ret.sgn=ret.num[0]!=1||ret.num[1];
        b.sgn=b.num[0]!=1||ret.num[1];
        return ret ;
    }
    inline int length()
    {
        return :: length(num);
    }
    inline int zeronum()
    {
        return :: zeronum(num);
    }
    inline bignum C(const int m,const int n)
    {
        combination(num,m,n);
        sgn=1 ;
        return*this ;
    }
    inline bignum P(const int m,const int n)
    {
        permutation(num,m,n);
        sgn=1 ;
        return*this ;
    }
};
//int main()
//{
//    bignum a,b,c;
//    cin>>a>>b;
//    cout<<"加法:"<<a+b<<endl;
//    cout<<"减法:"<<a-b<<endl;
//    cout<<"乘法:"<<a*b<<endl;
//    cout<<"除法:"<<a/b<<endl;
//    c=sqrt(a);
//    cout<<"平方根:"<<c<<endl;
//    cout<<"a的长度:"<<a.length()<<endl;
//    cout<<"a的末尾0个数:"<<a.zeronum()<<endl<<endl;
//    cout<<"组合: 从10个不同元素取3个元素组合的所有可能性为"<<c.C(10,3)<<endl;
//    cout<<"排列: 从10个不同元素取3个元素排列的所有可能性为"<<c.P(10,3)<<endl;
//    return 0 ;
//}


int main()
{
    int t;
    scanf("%d",&t);
    while(t--)
    {
        bignum n;
        cin>>n;
        bignum ans;
        ans= ((n - 2) * (n - 2) * (n - 1) / 2 - (n - 2) * (n * 2 - 3) * (n - 1) / 6 + (n - 1) * 2) * n / 4 + 1;
        cout<<ans<<endl;
    }
    return 0;
}

The second:

#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
#define PLUS 	1	// 正数。
#define MINUS 	-1	// 负数。
class integer
{
	friend ostream& operator<<(ostream&, const integer&);
	friend istream& operator>>(istream&, integer&);

	friend int compare(const integer, const integer);
	friend bool operator<(const integer, const integer);
	friend bool operator<=(const integer, const integer);

	friend integer operator<<(integer, int);

	friend integer operator+(integer, integer);
	friend integer operator-(integer, integer);
	friend integer operator*(integer, integer);
	friend integer operator/(integer, integer);
	friend integer operator^(integer, int);

public:
	integer() { };

	integer(int a)
	{
		signbit = (a >= 0 ? PLUS : MINUS);
		a = abs(a);
		while (a)
		{
			digits.push_back(a % 10);
			a /= 10;
		}
	};

	~integer() { };

	void zero_justify(void);

private:
	// 表示大数的结构。数位按低位到高位的顺序存放。存储的是数位值,而不是数位的字符值。
	// 数字 1 用 ASCII 码为 1 的字符,而不是 ‘1’ 来表示。
	vector < char > digits;	// 存放数位值。
	int signbit;		// 符号位。
};

integer operator+(integer, integer);
integer operator-(integer, integer);

// 重载输出符号<<。
ostream& operator<<(ostream& os, const integer& n)
{
	// 当为自然数时,不输出“+”号。
	os << (n.signbit > 0 ? "" : "-");
	for (int i = n.digits.size() - 1; i >= 0; i--)
		// 存放的是数位值,输出时要转换为数位的字符值。
		os << (char)('0' + n.digits[i]);
	return os;
}

// 重载输入符号>>。
istream& operator>>(istream& in, integer& n)
{
	// 读入表示大整数的字符串。
	string s;
	in >> s;

	if (s.length() == 0)
	{
		// 若长度为0,表示读入的是一个空字符串,应该要给予错误提示,但对于本题来说,不
		// 存在这种情况,故不考虑。若要完善,需要进一步处理此种情况。
	}

	// 在解析之前,理应判断该字符串是否是一个合法的大数表示,即开始一位为符号位,为“+”或
	// “-”,正整数“+”可以忽略,后面应该全部是数字字符,且不包含前导0。由于本题不存在此种情
	// 况,故不考虑,若要完善需进一步处理此种情况。

	// 解析符号位。
	if (isdigit(s[0]))
		n.signbit = PLUS;
	else
	{
		n.signbit = (s[0] == '+' ? PLUS : MINUS);
		s.erase(s.begin());
	}

	// 解析数字位,从低位到高位存放于动态数组中。
	n.digits.clear();
	for (int i = s.length() - 1; i >= 0; i--)
		n.digits.push_back((char)(s[i] - '0'));

	return in;
}

// 移除大数运算产生的前导0。
void integer::zero_justify(void)
{
	for (int i = digits.size() - 1; i >= 1; i--)
		if (digits[i] == 0)
			digits.erase(digits.begin() + i);
		else
			break;

	if (digits.size() == 1 && digits[0] == 0)
		signbit = PLUS;
}

// 比较两个数的大小,若相等,返回 0,若 a 大于 b,返回 1,若 a 小于 b,返回 -1。
int compare(const integer a, const integer b)
{
	// 若 a 为正,b 为负,则有 a 大于 b。
	if (a.signbit == PLUS && b.signbit == MINUS)
		return PLUS;

	// 若 a 为负,b 为正,则 a 小于 b。
	if (a.signbit == MINUS && b.signbit == PLUS)
		return MINUS;

	// 若两数符号相同,则 a 的数位长度大于 b 的数位长度,若 a 为正数,则有 a 大于 b,若 a
	// 为负数,有 a 小于 b,则将 a 的符号位乘以1作为结果返回即可。
	if (a.digits.size() > b.digits.size())
		return PLUS * a.signbit;

	// 若两数符号相同,若a的数位长度小于b的数位长度,若 a 为正数,则 a 小于 b,若 a 为负数,
	// 则 a 大于 b,则将 a 的符号位乘以 -1 作为结果返回即可。
	if (a.digits.size() < b.digits.size())
		return MINUS * a.signbit;

	// 两个数的数位长度相等,符号相等,则从低位到高位逐个比较数位值的大小。
	int marker = a.digits.size() - 1;
	while (marker >= 0)
	{
		if (a.digits[marker] > b.digits[marker])
			return PLUS * a.signbit;

		if (a.digits[marker] < b.digits[marker])
			return MINUS * a.signbit;

		marker--;
	}

	return 0;
}

// 小于比较符。
bool operator<(const integer a, const integer b)
{
	return compare(a, b) < 0;
}

// 小于等于比较符。
bool operator<=(const integer a, const integer b)
{
	return compare(a, b) <= 0;
}

// 左移操作。b 表示左移的位数。即将 a 乘以 10^b。
integer operator<<(integer a, int b)
{
	integer c = a;

	// 若 a 等于 0,则移位后仍为 0。
	if (a.digits.size() == 1 && a.digits[0] == 0)
		return c;

	// 向左移动 b 位,相当于在数位数组前插入 b 个 0。
	for (int i = 0; i < b; i++)
		c.digits.insert(c.digits.begin(), (char)(0));

	return c;
}

// 加法运算。从低位往高位进行,每一位相加产生的进位向高位传递,注意负数的处理,可以相应的
// 转变为减法来简化操作。
integer operator+(integer a, integer b)
{
	integer c;

	// 两数符号位相等,则最终符号位和原来的加数符号位相同。
	if (a.signbit == b.signbit)
		c.signbit = a.signbit;
	else
	{
		// 若两个加数为一正一负,则将其转换为减法操作。
		if (a.signbit == MINUS)
		{
			a.signbit = PLUS;
			c = b - a;
		}
		else
		{
			b.signbit = PLUS;
			c = a - b;
		}

		return c;
	}

	// 从动态数组的开始即低位开始相加,逐渐往前进位,如果有的话。
	int carry = 0;		// 进位。
	int maxsize = max(a.digits.size(), b.digits.size());
	int marker = 0;

	// 为两数添加前导 0,以使得数位相同,便于计算。
	while (a.digits.size() < maxsize)
		a.digits.push_back(char(0));
	while (b.digits.size() < maxsize)
		b.digits.push_back(char(0));

	// 逐位相加。
	while (marker < maxsize)
	{
		int t = a.digits[marker] + b.digits[marker] + carry;
		carry = t / 10;
		c.digits.push_back((char)(t % 10));

		marker++;
	}

	// 若最后一次进位为 1,则需在最高位加 1。
	if (carry)
		c.digits.push_back((char)(1));

	c.zero_justify();

	return c;
}

// 减法。为了保证借位能够成功终止,最好确保被减数不小于减数。同样可以在适当情况转变为加法来简化操作。
integer operator-(integer a, integer b)
{
	integer c;

	// 当某一个数为负数时,转换为加法。
	if (a.signbit == MINUS || b.signbit == MINUS)
	{
		b.signbit = MINUS * b.signbit;
		c = a + b;

		return c;
	}

	// 两个都为正数,若 a < b,则尽量保证被减数大于减数。
	if (a < b)
	{
		c = b - a;
		c.signbit = MINUS;

		return c;
	}
	else
		c.signbit = PLUS;

	int borrow = 0;		// 借位。
	int maxsize = a.digits.size();	// 被减数大于减数。
	int marker = 0;		// 计数器。

	// 为减数添加前导 0,便于计算。因为先前已经使得 a > b 且 a 和 b 均为正数。
	while (b.digits.size() < maxsize)
		b.digits.push_back(char(0));

	// 从低位开始逐位相减,不够的向高位借位。
	while (marker < maxsize)
	{
		int v = a.digits[marker] - borrow - b.digits[marker];
		if (v < 0)
		{
			v += 10;
			borrow = 1;
		}
		else
			borrow = 0;

		c.digits.push_back((char)(v % 10));

		marker++;
	}

	c.zero_justify();

	return c;
}

// 乘法,采用一行一行算的方法比单纯的反复加法更快且编写代码不会变复杂许多。每次操作都把第一个
// 乘数左移一个数位,然后把左移后的数乘以x的积加到最终结果中,其中x是第二个乘数对应的数字。尽
// 管用反复加法来实现这一步看起来不够精巧,但由于对于第二个乘数的每个数字,内层循环最多执行 9
// 次,实际上并没有浪费太多的时间,左移一个数位等价于用它乘以进位制的基数,在十进制里就是乘以 10。
integer operator*(integer a, integer b)
{
	integer c = integer(0), row = a;
	row.signbit = PLUS;

	for (int i = 0; i < b.digits.size(); i++)
	{
		for (int j = 0; j < b.digits[i]; j++)
			c = (c + row);

		row = row << 1;
	}

	c.signbit = a.signbit * b.signbit;
	c.zero_justify();

	return c;
}

// 除法运算。将余数和商不断左移,余数加上被除数的下一个数字,然后尝试减去除数。
integer operator/(integer a, integer b)
{
	integer c, row;
	row.signbit = PLUS;

	// 商的符号为 a 的符号乘以 b 的符号。
	c.signbit = a.signbit * b.signbit;

	int v;
	// 从数a的最高位开始除。
	for (int i = a.digits.size() - 1; i >= 0; i--)
	{
		row = row << 1;
		row.digits[0] = a.digits[i];

		// 当除数小于被除数,减去除数,对应位的商增 1。
		v = 0;
		while (b <= row)
		{
			v++;
			row = row - b;
		}

		// 将商左移 1 位,刚得到的商即为最低位。
		c = c << 1;
		c.digits[0] = (char)(v);
	}

	c.zero_justify();

	return c;
}

// 幂计算。幂就是反复作乘法,利用:a^n = a^(n / 2) * a^(n / 2) * a^(n mod 2),可以减少乘
// 的次数。
integer operator^(integer a, int b)
{
	if (b == 0)
		return integer(1);

	if (b == 1)
		return a;

	if (b == 2)
		return a * a;

	return ((a ^ (b / 2)) ^ 2) * (a ^ (b % 2));
}

int main(int ac, char *av[])
{
	int cases;
	integer a;

	cin >> cases;
	while (cases--)
	{
		cin >> a;
		cout << ((a ^ 4) - integer(6) * (a ^ 3) +
			integer(23) * (a ^ 2) - integer(18) * a +
			integer(24)) / integer(24) << endl;
	}

	return 0;
}


你可能感兴趣的:(【UVA】10213 - How Many Pieces of Land ?(大树模板X2))