萌新求助怎么算负数的加法

P1001 A+B Problem

HAuCl4 @ 2022-12-24 11:20:31

RT,使用 int2048

这是50分代码:

#include<stdio.h>
#include<initializer_list>
#define uint128_t __uint128_t
static const char HEXDIGITS[]="0123456789abcdefghijklmnopqrstuvwxyz";
static const char HEXDIGITSUPPER[]="0123456789ABCDEFGHIJKLMNOPQRSTUVWXYZ";
struct uint256_t;
struct uint256_t{
    uint128_t up=0,low=0;
    uint256_t(){}
    template<typename _Tp>
    uint256_t(const _Tp x){up=x<0?-1:0;low=x;}
    uint256_t(const unsigned __int128 x){low=x;}
    uint256_t(std::initializer_list<uint128_t>initlist){
        up=*initlist.begin();
        low=*(initlist.begin()+1);
    }
    inline uint256_t operator+=(const uint256_t& x);
    inline uint256_t operator-=(const uint256_t& x);
    inline uint256_t operator*=(const uint256_t& x);
    inline uint256_t operator/=(const uint256_t& x);
    inline uint256_t operator%=(const uint256_t& x);
    inline uint256_t operator<<=(const int x);
    inline uint256_t operator>>=(const int x);
    inline uint256_t operator&=(const uint256_t& x);
    inline uint256_t operator|=(const uint256_t& x);
    inline uint256_t operator^=(const uint256_t& x);
    inline operator unsigned __int128(){
        return low;
    }
    inline char* c_str();
};
inline uint256_t operator&(const uint256_t& number1,const uint256_t& number2){return{number1.up&number2.up,number1.low&number2.low};}
inline uint256_t operator|(const uint256_t& number1,const uint256_t& number2){return{number1.up|number2.up,number1.low|number2.low};}
inline uint256_t operator~(const uint256_t& number){return{~number.up,~number.low};}
inline uint256_t operator^(const uint256_t& number1,const uint256_t& number2){return{number1.up^number2.up,number1.low^number2.low};}
inline bool zero256(const uint256_t& number){return !number.up&&!number.low;}
inline uint256_t operator<<(const uint256_t& number,const int x){return x>=256?0:x==128?uint256_t{number.low,0}:!x?number:x<128?uint256_t{(number.up<<x)+(number.low>>(128-x)),number.low<<x}:256>x&&x>128?uint256_t{number.low<<(x-128),0}:(uint256_t)0;}
inline uint256_t operator>>(const uint256_t& number,const int x){return x>=256?0:x==128?uint256_t{0,number.up}:!x?number:x<128?uint256_t{number.up>>x,(number.up<<(128-x))+(number.low>>x)}:256>x&&x>128?uint256_t{0,number.up>>(x-128)}:(uint256_t)0;}
inline int bits256(const uint256_t& number){
    int result=0;
    if(number.up){
        result=128;
        for(uint128_t up=number.up;up;++result)
            up>>=1;
    }else
        for(uint128_t low=number.low;low;++result)
            low>>=1;
    return result;
}
inline bool Bool(const uint256_t& x){return x.up||x.low;}
inline bool operator==(const uint256_t& number1,const uint256_t& number2){return number1.up==number2.up&&number1.low==number2.low;}
inline bool operator!=(const uint256_t& number1,const uint256_t& number2){return!(number1==number2);}
inline bool operator>(const uint256_t& number1,const uint256_t& number2){return number1.up==number2.up?number1.low>number2.low:number1.up>number2.up;}
inline bool operator>=(const uint256_t& number1,const uint256_t& number2){return number1>number2||number1==number2;}
inline bool operator<(const uint256_t& number1,const uint256_t& number2){return!(number1>=number2);}
inline bool operator<=(const uint256_t& number1,const uint256_t& number2){return!(number1>number2);}
inline bool operator&&(const uint256_t& number1,const uint256_t& number2){return Bool(number1)&&Bool(number2);}
inline bool operator||(const uint256_t& number1,const uint256_t& number2){return Bool(number1)||Bool(number2);}
inline bool operator!(const uint256_t& number){return!(number.up||number.low);}
inline uint256_t operator+(const uint256_t& number1,const uint256_t& number2){return{number1.up+number2.up+(number1.low+number2.low<number1.low),number1.low+number2.low};}
inline uint256_t operator-(const uint256_t& number1,const uint256_t& number2){return{number1.up-number2.up-(number1.low-number2.low>number1.low),number1.low-number2.low};}
inline uint256_t operator-(const uint256_t& number){return{-number.up,-number.low};}
inline uint256_t operator*(const uint256_t& number1,const uint256_t& number2){
    uint256_t target,tmp,tmp2;
    uint128_t
    top[4]={number1.up>>64,number1.up&0xffffffffffffffff,number1.low>>64,number1.low&0xffffffffffffffff},
    bottom[4]={number2.up>>64,number2.up&0xffffffffffffffff,number2.low>>64,number2.low&0xffffffffffffffff},products[4][4];
    for(signed char y=3;y>=0;--y)
        for(signed char x=3;x>=0;--x)
            products[3-x][y]=top[x]*bottom[y];
    uint128_t fourth64=products[0][3]&0xffffffffffffffff;
    uint128_t third64=(products[0][2]&0xffffffffffffffff)+(products[0][3]>>64)+(products[1][3]&0xffffffffffffffff);
    uint128_t second64=(products[0][1]&0xffffffffffffffff)+(products[0][2]>>64)+(products[1][2]&0xffffffffffffffff)+(products[1][3]>>64)+(products[2][3]&0xffffffffffffffff);
    uint128_t first64=(products[0][0]&0xffffffffffffffff)+(products[0][1]>>64)+(products[1][1]&0xffffffffffffffff)+(products[1][2]>>64)+(products[2][2]&0xffffffffffffffff)+(products[2][3]>>64)+(products[3][3]&0xffffffffffffffff);
    return(uint256_t)fourth64+uint256_t{second64,0}+uint256_t{first64<<64,0}+uint256_t{third64>>64,third64<<64};
}
inline void divmod256(const uint256_t &l,const uint256_t &r,uint256_t &retDiv,uint256_t &retMod){
    uint256_t copyd,adder,resDiv=0,resMod=l;
    const int diffBits=bits256(l)-bits256(r);
    if(r>l){
        retMod=l;
        retDiv=0;
    }else{
        copyd=r<<diffBits;
        adder=uint256_t(1)<<diffBits;
        if(copyd>resMod){
            copyd=copyd>>1;
            adder=adder>>1;
        }
        while(resMod>=r){
            if(resMod>=copyd){
                resMod=resMod-copyd;
                resDiv=resDiv|adder;
            }
            copyd=copyd>>1;
            adder=adder>>1;
        }
        retDiv=resDiv;
        retMod=resMod;
    }
}
inline uint256_t operator/(const uint256_t& l,const uint256_t& r){
    uint256_t copyd,adder,resDiv=0,resMod=l,retDiv;
    const int diffBits=bits256(l)-bits256(r);
    if(r>l)retDiv=0;
    else{
        copyd=r<<diffBits;
        adder=uint256_t(1)<<diffBits;
        if(copyd>resMod){
            copyd=copyd>>1;
            adder=adder>>1;
        }
        while(resMod>=r){
            if(resMod>=copyd){
                resMod=resMod-copyd;
                resDiv=resDiv|adder;
            }
            copyd=copyd>>1;
            adder=adder>>1;
        }
        retDiv=resDiv;
    }return retDiv;
}
inline uint256_t operator%(const uint256_t& l,const uint256_t& r){return l-l/r*r;}
inline uint256_t uint256_t::operator+=(const uint256_t& r){return *this=*this+r;}
inline uint256_t uint256_t::operator-=(const uint256_t& r){return *this=*this-r;}
inline uint256_t uint256_t::operator*=(const uint256_t& r){return *this=*this*r;}
inline uint256_t uint256_t::operator/=(const uint256_t& r){return *this=*this/r;}
inline uint256_t uint256_t::operator%=(const uint256_t& r){return *this=*this%r;}
inline uint256_t uint256_t::operator<<=(const int r){return *this=*this<<r;}
inline uint256_t uint256_t::operator>>=(const int r){return *this=*this>>r;}
inline uint256_t uint256_t::operator&=(const uint256_t& r){return *this=*this&r;}
inline uint256_t uint256_t::operator|=(const uint256_t& r){return *this=*this&r;}
inline static void reverseString(char* str,const unsigned long long length){
    for(unsigned long long i=0,j=length-1;i<j;++i,--j)
        str[i]^=str[j]^=str[i]^=str[j];
}
inline void tostring256(const uint256_t& number,const unsigned char base,char *out,unsigned long long outLength){
    uint256_t rDiv=number,rMod=0;
    unsigned long long offset=0;
    if(base<2||base>36)return;
    do{
        if(offset>outLength-1)return;
        divmod256(rDiv,base,rDiv,rMod);
        out[offset++]=HEXDIGITS[rMod.low];
    }while(!zero256(rDiv));
    out[offset]=0;
    reverseString(out,offset);
}
inline void tostring256_upper(uint256_t& number,const unsigned char base,char *out,unsigned long long outLength){
    uint256_t rDiv=number,rMod=0;
    unsigned long long offset=0;
    if(base<2||base>36)return;
    do{
        if(offset>outLength-1)return;
        divmod256(rDiv,base,rDiv,rMod);
        out[offset++]=HEXDIGITSUPPER[rMod.low];
    }while(!zero256(rDiv));
    out[offset]=0;
    reverseString(out,offset);
}
inline void tostring256(uint256_t& number,const unsigned char base,char *out,unsigned long long outLength,const char* BaseMap){
    uint256_t rDiv=number,rMod=0;
    unsigned long long offset=0;
    if(base<2||base>36)return;
    do{
        if(offset>outLength-1)return;
        divmod256(rDiv,base,rDiv,rMod);
        out[offset++]=BaseMap[rMod.low];
    }while(!zero256(rDiv));
    out[offset]=0;
    reverseString(out,offset);
}
inline char* uint256_t::c_str(){
    static char Str[80];
    tostring256(*this,10,Str,80);
    return Str;
}
struct uint512_t;
struct uint512_t{
    uint256_t up=0,low=0;
    uint512_t(){}
    template<typename _Tp>
    uint512_t(const _Tp x){up=x<0?-1:0;low=x;}
    uint512_t(const bool x){low=x?1:0;}
    uint512_t(const uint256_t& x){up=0;low=x;}
    uint512_t(std::initializer_list<uint256_t>initlist){
        up=*initlist.begin();
        low=*(initlist.begin()+1);
    }
    inline uint512_t operator+=(const uint512_t& x);
    inline uint512_t operator-=(const uint512_t& x);
    inline uint512_t operator*=(const uint512_t& x);
    inline uint512_t operator/=(const uint512_t& x);
    inline uint512_t operator%=(const uint512_t& x);
    inline uint512_t operator<<=(const int x);
    inline uint512_t operator>>=(const int x);
    inline uint512_t operator&=(const uint512_t& x);
    inline uint512_t operator|=(const uint512_t& x);
    inline uint512_t operator^=(const uint512_t& x);
    inline char* c_str();
};
inline uint512_t operator&(const uint512_t& number1,const uint512_t& number2){return{number1.up&number2.up,number1.low&number2.low};}
inline uint512_t operator|(const uint512_t& number1,const uint512_t& number2){return{number1.up|number2.up,number1.low|number2.low};}
inline uint512_t operator~(const uint512_t& number){return{~number.up,~number.low};}
inline uint512_t operator^(const uint512_t& number1,const uint512_t& number2){return{number1.up^number2.up,number1.low^number2.low};}
inline bool zero512(const uint512_t& number){return !number.up&&!number.low;}
inline uint512_t operator<<(const uint512_t& number,const int x){return x>=512?0:x==256?uint512_t{number.low,0}:!x?number:x<256?uint512_t{(number.up<<x)+(number.low>>(256-x)),number.low<<x}:512>x&&x>256?uint512_t{number.low<<(x-256),0}:0;}
inline uint512_t operator>>(const uint512_t& number,const int x){return x>=512?0:x==256?uint512_t{0,number.up}:!x?number:x<256?uint512_t{number.up>>x,(number.up<<256-x)+(number.low>>x)}:512>x&&x>256?uint512_t{0,number.up>>(x-256)}:0;}
inline int bits512(const uint512_t& number){
    int result=0;
    if(Bool(number.up)){
        result=256;
        for(uint256_t up=number.up;Bool(up);++result)
            up>>=1;
    }else
        for(uint256_t low=number.low;Bool(low);++result)
            low>>=1;
    return result;
}
inline bool Bool(const uint512_t& x){return x.up||x.low;}
inline bool operator==(const uint512_t& number1,const uint512_t& number2){return number1.up==number2.up&&number1.low==number2.low;}
inline bool operator!=(const uint512_t& number1,const uint512_t& number2){return!(number1==number2);}
inline bool operator>(const uint512_t& number1,const uint512_t& number2){return number1.up==number2.up?number1.low>number2.low:number1.up>number2.up;}
inline bool operator>=(const uint512_t& number1,const uint512_t& number2){return number1>number2||number1==number2;}
inline bool operator<(const uint512_t& number1,const uint512_t& number2){return!(number1>=number2);}
inline bool operator<=(const uint512_t& number1,const uint512_t& number2){return!(number1>number2);}
inline bool operator&&(const uint512_t& number1,const uint512_t& number2){return Bool(number1)&&Bool(number2);}
inline bool operator||(const uint512_t& number1,const uint512_t& number2){return Bool(number1)||Bool(number2);}
inline bool operator!(const uint512_t& number){return!(number.up||number.low);}
inline uint512_t operator+(const uint512_t& number1,const uint512_t& number2){return{number1.up+number2.up+uint256_t(number1.low+number2.low<number1.low),number1.low+number2.low};}
inline uint512_t operator-(const uint512_t& number1,const uint512_t& number2){return{number1.up-number2.up-uint256_t(number1.low-number2.low>number1.low),number1.low-number2.low};}
inline uint512_t operator-(const uint512_t& number){return{-number.up,-number.low};}
inline uint512_t operator*(const uint512_t& number1,const uint512_t& number2){
    uint512_t target,tmp,tmp2;
    uint256_t
    top[4]={number1.up>>128,number1.up&uint256_t(uint128_t(-1)),number1.low>>128,number1.low&uint256_t(uint128_t(-1))},
    bottom[4]={number2.up>>128,number2.up&uint256_t(uint128_t(-1)),number2.low>>128,number2.low&uint256_t(uint128_t(-1))},products[4][4];
    for(signed char y=3;y>=0;--y)
        for(signed char x=3;x>=0;--x)
            products[3-x][y]=top[x]*bottom[y];
    uint256_t fourth128=products[0][3]&uint256_t(uint128_t(-1));
    uint256_t third128=(products[0][2]&uint256_t(uint128_t(-1)))+(products[0][3]>>128)+(products[1][3]&uint256_t(uint128_t(-1)));
    uint256_t second128=(products[0][1]&uint256_t(uint128_t(-1)))+(products[0][2]>>128)+(products[1][2]&uint256_t(uint128_t(-1)))+(products[1][3]>>128)+(products[2][3]&uint256_t(uint128_t(-1)));
    uint256_t first128=(products[0][0]&uint256_t(uint128_t(-1)))+(products[0][1]>>128)+(products[1][1]&uint256_t(uint128_t(-1)))+(products[1][2]>>128)+(products[2][2]&uint256_t(uint128_t(-1)))+(products[2][3]>>128)+(products[3][3]&uint256_t(uint128_t(-1)));
    return (uint512_t)fourth128+uint512_t{second128,0}+uint512_t{first128<<128,0}+uint512_t{third128>>128,third128<<128};
}
inline void divmod512(const uint512_t &l,const uint512_t &r,uint512_t &retDiv,uint512_t &retMod){
    uint512_t copyd,adder,resDiv=0,resMod=l;
    const int diffBits=bits512(l)-bits512(r);
    if(r>l){
        retMod=l;
        retDiv=0;
    }else{
        copyd=r<<diffBits;
        adder=uint512_t(1)<<diffBits;
        if(copyd>resMod){
            copyd=copyd>>1;
            adder=adder>>1;
        }
        while(resMod>=r){
            if(resMod>=copyd){
                resMod=resMod-copyd;
                resDiv=resDiv|adder;
            }
            copyd=copyd>>1;
            adder=adder>>1;
        }
        retDiv=resDiv;
        retMod=resMod;
    }
}
inline uint512_t operator/(const uint512_t& l,const uint512_t& r){
    uint512_t copyd,adder,resDiv=0,resMod=l,retDiv;
    const int diffBits=bits512(l)-bits512(r);
    if(r>l)retDiv=0;
    else{
        copyd=r<<diffBits;
        adder=uint512_t(1)<<diffBits;
        if(copyd>resMod){
            copyd=copyd>>1;
            adder=adder>>1;
        }
        while(resMod>=r){
            if(resMod>=copyd){
                resMod=resMod-copyd;
                resDiv=resDiv|adder;
            }
            copyd=copyd>>1;
            adder=adder>>1;
        }
        retDiv=resDiv;
    }return retDiv;
}
inline uint512_t operator%(const uint512_t& l,const uint512_t& r){return l-l/r*r;}
inline uint512_t uint512_t::operator+=(const uint512_t& r){return *this=*this+r;}
inline uint512_t uint512_t::operator-=(const uint512_t& r){return *this=*this-r;}
inline uint512_t uint512_t::operator*=(const uint512_t& r){return *this=*this*r;}
inline uint512_t uint512_t::operator/=(const uint512_t& r){return *this=*this/r;}
inline uint512_t uint512_t::operator%=(const uint512_t& r){return *this=*this%r;}
inline uint512_t uint512_t::operator<<=(const int r){return *this=*this<<r;}
inline uint512_t uint512_t::operator>>=(const int r){return *this=*this>>r;}
inline uint512_t uint512_t::operator&=(const uint512_t& r){return *this=*this&r;}
inline uint512_t uint512_t::operator|=(const uint512_t& r){return *this=*this&r;}
inline void tostring512(const uint512_t& number,const unsigned char base,char *out,unsigned long long outLength){
    uint512_t rDiv=number,rMod=0;
    unsigned long long offset=0;
    if(base<2||base>36)return;
    do{
        if(offset>outLength-1)return;
        divmod512(rDiv,base,rDiv,rMod);
        out[offset++]=HEXDIGITS[rMod.low.low];
    }while(!zero512(rDiv));
    out[offset]=0;
    reverseString(out,offset);
}
inline void tostring512_upper(uint512_t& number,const unsigned char base,char *out,unsigned long long outLength){
    uint512_t rDiv=number,rMod=0;
    unsigned long long offset=0;
    if(base<2||base>36)return;
    do{
        if(offset>outLength-1)return;
        divmod512(rDiv,base,rDiv,rMod);
        out[offset++]=HEXDIGITSUPPER[rMod.low.low];
    }while(!zero512(rDiv));
    out[offset]=0;
    reverseString(out,offset);
}
inline void tostring512(uint512_t& number,const unsigned char base,char *out,unsigned long long outLength,const char* BaseMap){
    uint512_t rDiv=number,rMod=0;
    unsigned long long offset=0;
    if(base<2||base>36)return;
    do{
        if(offset>outLength-1)return;
        divmod512(rDiv,base,rDiv,rMod);
        out[offset++]=BaseMap[rMod.low.low];
    }while(!zero512(rDiv));
    out[offset]=0;
    reverseString(out,offset);
}
inline char* uint512_t::c_str(){
    static char Str[160];
    tostring512(*this,10,Str,160);
    return Str;
}
struct uint1024_t;
struct uint1024_t{
    uint512_t up=0,low=0;
    uint1024_t(){}
    template<typename _Tp>
    uint1024_t(const _Tp x){up=x<0?-1:0;low=x;}
    uint1024_t(const bool x){low=x?1:0;}
    uint1024_t(const uint512_t& x){up=0;low=x;}
    uint1024_t(std::initializer_list<uint512_t>initlist){
        up=*initlist.begin();
        low=*(initlist.begin()+1);
    }
    inline uint1024_t operator+=(const uint1024_t& x);
    inline uint1024_t operator-=(const uint1024_t& x);
    inline uint1024_t operator*=(const uint1024_t& x);
    inline uint1024_t operator/=(const uint1024_t& x);
    inline uint1024_t operator%=(const uint1024_t& x);
    inline uint1024_t operator<<=(const int x);
    inline uint1024_t operator>>=(const int x);
    inline uint1024_t operator&=(const uint1024_t& x);
    inline uint1024_t operator|=(const uint1024_t& x);
    inline uint1024_t operator^=(const uint1024_t& x);
    inline char* c_str();
};
inline uint1024_t operator&(const uint1024_t& number1,const uint1024_t& number2){return{number1.up&number2.up,number1.low&number2.low};}
inline uint1024_t operator|(const uint1024_t& number1,const uint1024_t& number2){return{number1.up|number2.up,number1.low|number2.low};}
inline uint1024_t operator~(const uint1024_t& number){return{~number.up,~number.low};}
inline uint1024_t operator^(const uint1024_t& number1,const uint1024_t& number2){return{number1.up^number2.up,number1.low^number2.low};}
inline bool zero1024(const uint1024_t& number){return !number.up&&!number.low;}
inline uint1024_t operator<<(const uint1024_t& number,const int x){return x>=1024?0:x==512?uint1024_t{number.low,0}:!x?number:x<512?uint1024_t{(number.up<<x)+(number.low>>(512-x)),number.low<<x}:1024>x&&x>512?uint1024_t{number.low<<(x-512),0}:0;}
inline uint1024_t operator>>(const uint1024_t& number,const int x){return x>=1024?0:x==512?uint1024_t{0,number.up}:!x?number:x<512?uint1024_t{number.up>>x,(number.up<<512-x)+(number.low>>x)}:1024>x&&x>512?uint1024_t{0,number.up>>(x-512)}:0;}
inline int bits1024(const uint1024_t& number){
    int result=0;
    if(Bool(number.up)){
        result=512;
        for(uint512_t up=number.up;Bool(up);++result)
            up>>=1;
    }else
        for(uint512_t low=number.low;Bool(low);++result)
            low>>=1;
    return result;
}
inline bool Bool(const uint1024_t& x){return x.up||x.low;}
inline bool operator==(const uint1024_t& number1,const uint1024_t& number2){return number1.up==number2.up&&number1.low==number2.low;}
inline bool operator!=(const uint1024_t& number1,const uint1024_t& number2){return!(number1==number2);}
inline bool operator>(const uint1024_t& number1,const uint1024_t& number2){return number1.up==number2.up?number1.low>number2.low:number1.up>number2.up;}
inline bool operator>=(const uint1024_t& number1,const uint1024_t& number2){return number1>number2||number1==number2;}
inline bool operator<(const uint1024_t& number1,const uint1024_t& number2){return!(number1>=number2);}
inline bool operator<=(const uint1024_t& number1,const uint1024_t& number2){return!(number1>number2);}
inline bool operator&&(const uint1024_t& number1,const uint1024_t& number2){return Bool(number1)&&Bool(number2);}
inline bool operator||(const uint1024_t& number1,const uint1024_t& number2){return Bool(number1)||Bool(number2);}
inline bool operator!(const uint1024_t& number){return!(number.up||number.low);}
inline uint1024_t operator+(const uint1024_t& number1,const uint1024_t& number2){return{number1.up+number2.up+uint512_t(number1.low+number2.low<number1.low),number1.low+number2.low};}
inline uint1024_t operator-(const uint1024_t& number1,const uint1024_t& number2){return{number1.up-number2.up-uint512_t(number1.low-number2.low>number1.low),number1.low-number2.low};}
inline uint1024_t operator-(const uint1024_t& number){return{-number.up,-number.low};}
inline uint1024_t operator*(const uint1024_t& number1,const uint1024_t& number2){
    uint1024_t target,tmp,tmp2;
    uint512_t
    top[4]={number1.up>>256,number1.up&uint512_t(uint256_t(-1)),number1.low>>256,number1.low&uint512_t(uint256_t(-1))},
    bottom[4]={number2.up>>256,number2.up&uint512_t(uint256_t(-1)),number2.low>>256,number2.low&uint512_t(uint256_t(-1))},products[4][4];
    for(signed char y=3;y>=0;--y)
        for(signed char x=3;x>=0;--x)
            products[3-x][y]=top[x]*bottom[y];
    uint512_t fourth256=products[0][3]&uint512_t(uint256_t(-1));
    uint512_t third256=(products[0][2]&uint512_t(uint256_t(-1)))+(products[0][3]>>256)+(products[1][3]&uint512_t(uint256_t(-1)));
    uint512_t second256=(products[0][1]&uint512_t(uint256_t(-1)))+(products[0][2]>>256)+(products[1][2]&uint512_t(uint256_t(-1)))+(products[1][3]>>256)+(products[2][3]&uint512_t(uint256_t(-1)));
    uint512_t first256=(products[0][0]&uint512_t(uint256_t(-1)))+(products[0][1]>>256)+(products[1][1]&uint512_t(uint256_t(-1)))+(products[1][2]>>256)+(products[2][2]&uint512_t(uint256_t(-1)))+(products[2][3]>>256)+(products[3][3]&uint512_t(uint256_t(-1)));
    return (uint1024_t)fourth256+uint1024_t{second256,0}+uint1024_t{first256<<256,0}+uint1024_t{third256>>256,third256<<256};
}
inline void divmod1024(const uint1024_t &l,const uint1024_t &r,uint1024_t &retDiv,uint1024_t &retMod){
    uint1024_t copyd,adder,resDiv=0,resMod=l;
    const int diffBits=bits1024(l)-bits1024(r);
    if(r>l){
        retMod=l;
        retDiv=0;
    }else{
        copyd=r<<diffBits;
        adder=uint1024_t(1)<<diffBits;
        if(copyd>resMod){
            copyd=copyd>>1;
            adder=adder>>1;
        }
        while(resMod>=r){
            if(resMod>=copyd){
                resMod=resMod-copyd;
                resDiv=resDiv|adder;
            }
            copyd=copyd>>1;
            adder=adder>>1;
        }
        retDiv=resDiv;
        retMod=resMod;
    }
}
inline uint1024_t operator/(const uint1024_t& l,const uint1024_t& r){
    uint1024_t copyd,adder,resDiv=0,resMod=l,retDiv;
    const int diffBits=bits1024(l)-bits1024(r);
    if(r>l)retDiv=0;
    else{
        copyd=r<<diffBits;
        adder=uint1024_t(1)<<diffBits;
        if(copyd>resMod){
            copyd=copyd>>1;
            adder=adder>>1;
        }
        while(resMod>=r){
            if(resMod>=copyd){
                resMod=resMod-copyd;
                resDiv=resDiv|adder;
            }
            copyd=copyd>>1;
            adder=adder>>1;
        }
        retDiv=resDiv;
    }return retDiv;
}
inline uint1024_t operator%(const uint1024_t& l,const uint1024_t& r){return l-l/r*r;}
inline uint1024_t uint1024_t::operator+=(const uint1024_t& r){return *this=*this+r;}
inline uint1024_t uint1024_t::operator-=(const uint1024_t& r){return *this=*this-r;}
inline uint1024_t uint1024_t::operator*=(const uint1024_t& r){return *this=*this*r;}
inline uint1024_t uint1024_t::operator/=(const uint1024_t& r){return *this=*this/r;}
inline uint1024_t uint1024_t::operator%=(const uint1024_t& r){return *this=*this%r;}
inline uint1024_t uint1024_t::operator<<=(const int r){return *this=*this<<r;}
inline uint1024_t uint1024_t::operator>>=(const int r){return *this=*this>>r;}
inline uint1024_t uint1024_t::operator&=(const uint1024_t& r){return *this=*this&r;}
inline uint1024_t uint1024_t::operator|=(const uint1024_t& r){return *this=*this&r;}
inline void tostring1024(const uint1024_t& number,const unsigned char base,char *out,unsigned long long outLength){
    uint1024_t rDiv=number,rMod=0;
    unsigned long long offset=0;
    if(base<2||base>36)return;
    do{
        if(offset>outLength-1)return;
        divmod1024(rDiv,base,rDiv,rMod);
        out[offset++]=HEXDIGITS[rMod.low.low];
    }while(!zero1024(rDiv));
    out[offset]=0;
    reverseString(out,offset);
}
inline void tostring1024_upper(uint1024_t& number,const unsigned char base,char *out,unsigned long long outLength){
    uint1024_t rDiv=number,rMod=0;
    unsigned long long offset=0;
    if(base<2||base>36)return;
    do{
        if(offset>outLength-1)return;
        divmod1024(rDiv,base,rDiv,rMod);
        out[offset++]=HEXDIGITSUPPER[rMod.low.low];
    }while(!zero1024(rDiv));
    out[offset]=0;
    reverseString(out,offset);
}
inline void tostring1024(uint1024_t& number,const unsigned char base,char *out,unsigned long long outLength,const char* BaseMap){
    uint1024_t rDiv=number,rMod=0;
    unsigned long long offset=0;
    if(base<2||base>36)return;
    do{
        if(offset>outLength-1)return;
        divmod1024(rDiv,base,rDiv,rMod);
        out[offset++]=BaseMap[rMod.low.low];
    }while(!zero1024(rDiv));
    out[offset]=0;
    reverseString(out,offset);
}
inline char* uint1024_t::c_str(){
    static char Str[320];
    tostring1024(*this,10,Str,320);
    return Str;
}
struct uint2048_t;
struct uint2048_t{
    uint1024_t up=0,low=0;
    uint2048_t(){}
    template<typename _Tp>
    uint2048_t(const _Tp x){up=x<0?-1:0;low=x;}
    uint2048_t(const bool x){low=x?1:0;}
    uint2048_t(const uint1024_t& x){up=0;low=x;}
    uint2048_t(std::initializer_list<uint1024_t>initlist){
        up=*initlist.begin();
        low=*(initlist.begin()+1);
    }
    inline uint2048_t operator+=(const uint2048_t& x);
    inline uint2048_t operator-=(const uint2048_t& x);
    inline uint2048_t operator*=(const uint2048_t& x);
    inline uint2048_t operator/=(const uint2048_t& x);
    inline uint2048_t operator%=(const uint2048_t& x);
    inline uint2048_t operator<<=(const int x);
    inline uint2048_t operator>>=(const int x);
    inline uint2048_t operator&=(const uint2048_t& x);
    inline uint2048_t operator|=(const uint2048_t& x);
    inline uint2048_t operator^=(const uint2048_t& x);
    inline char* c_str();
};
inline uint2048_t operator&(const uint2048_t& number1,const uint2048_t& number2){return{number1.up&number2.up,number1.low&number2.low};}
inline uint2048_t operator|(const uint2048_t& number1,const uint2048_t& number2){return{number1.up|number2.up,number1.low|number2.low};}
inline uint2048_t operator~(const uint2048_t& number){return{~number.up,~number.low};}
inline uint2048_t operator^(const uint2048_t& number1,const uint2048_t& number2){return{number1.up^number2.up,number1.low^number2.low};}
inline bool zero2048(const uint2048_t& number){return !number.up&&!number.low;}
inline uint2048_t operator<<(const uint2048_t& number,const int x){return x>=2048?0:x==1024?uint2048_t{number.low,0}:!x?number:x<1024?uint2048_t{(number.up<<x)+(number.low>>(1024-x)),number.low<<x}:2048>x&&x>1024?uint2048_t{number.low<<(x-1024),0}:0;}
inline uint2048_t operator>>(const uint2048_t& number,const int x){return x>=2048?0:x==1024?uint2048_t{0,number.up}:!x?number:x<1024?uint2048_t{number.up>>x,(number.up<<1024-x)+(number.low>>x)}:2048>x&&x>1024?uint2048_t{0,number.up>>(x-1024)}:0;}
inline int bits2048(const uint2048_t& number){
    int result=0;
    if(Bool(number.up)){
        result=1024;
        for(uint1024_t up=number.up;Bool(up);++result)
            up>>=1;
    }else
        for(uint1024_t low=number.low;Bool(low);++result)
            low>>=1;
    return result;
}
inline bool Bool(const uint2048_t& x){return x.up||x.low;}
inline bool operator==(const uint2048_t& number1,const uint2048_t& number2){return number1.up==number2.up&&number1.low==number2.low;}
inline bool operator!=(const uint2048_t& number1,const uint2048_t& number2){return!(number1==number2);}
inline bool operator>(const uint2048_t& number1,const uint2048_t& number2){return number1.up==number2.up?number1.low>number2.low:number1.up>number2.up;}
inline bool operator>=(const uint2048_t& number1,const uint2048_t& number2){return number1>number2||number1==number2;}
inline bool operator<(const uint2048_t& number1,const uint2048_t& number2){return!(number1>=number2);}
inline bool operator<=(const uint2048_t& number1,const uint2048_t& number2){return!(number1>number2);}
inline bool operator&&(const uint2048_t& number1,const uint2048_t& number2){return Bool(number1)&&Bool(number2);}
inline bool operator||(const uint2048_t& number1,const uint2048_t& number2){return Bool(number1)||Bool(number2);}
inline bool operator!(const uint2048_t& number){return!(number.up||number.low);}
inline uint2048_t operator+(const uint2048_t& number1,const uint2048_t& number2){return{number1.up+number2.up+uint1024_t(number1.low+number2.low<number1.low),number1.low+number2.low};}
inline uint2048_t operator-(const uint2048_t& number1,const uint2048_t& number2){return{number1.up-number2.up-uint1024_t(number1.low-number2.low>number1.low),number1.low-number2.low};}
inline uint2048_t operator-(const uint2048_t& number){return{-number.up,-number.low};}
inline uint2048_t operator*(const uint2048_t& number1,const uint2048_t& number2){
    uint2048_t target,tmp,tmp2;
    uint1024_t
    top[4]={number1.up>>512,number1.up&uint1024_t(uint512_t(-1)),number1.low>>512,number1.low&uint1024_t(uint512_t(-1))},
    bottom[4]={number2.up>>512,number2.up&uint1024_t(uint512_t(-1)),number2.low>>512,number2.low&uint1024_t(uint512_t(-1))},products[4][4];
    for(signed char y=3;y>=0;--y)
        for(signed char x=3;x>=0;--x)
            products[3-x][y]=top[x]*bottom[y];
    uint1024_t fourth512=products[0][3]&uint1024_t(uint512_t(-1));
    uint1024_t third512=(products[0][2]&uint1024_t(uint512_t(-1)))+(products[0][3]>>512)+(products[1][3]&uint1024_t(uint512_t(-1)));
    uint1024_t second512=(products[0][1]&uint1024_t(uint512_t(-1)))+(products[0][2]>>512)+(products[1][2]&uint1024_t(uint512_t(-1)))+(products[1][3]>>512)+(products[2][3]&uint1024_t(uint512_t(-1)));
    uint1024_t first512=(products[0][0]&uint1024_t(uint512_t(-1)))+(products[0][1]>>512)+(products[1][1]&uint1024_t(uint512_t(-1)))+(products[1][2]>>512)+(products[2][2]&uint1024_t(uint512_t(-1)))+(products[2][3]>>512)+(products[3][3]&uint1024_t(uint512_t(-1)));
    return (uint2048_t)fourth512+uint2048_t{second512,0}+uint2048_t{first512<<512,0}+uint2048_t{third512>>512,third512<<512};
}
inline void divmod2048(const uint2048_t &l,const uint2048_t &r,uint2048_t &retDiv,uint2048_t &retMod){
    uint2048_t copyd,adder,resDiv=0,resMod=l;
    const int diffBits=bits2048(l)-bits2048(r);
    if(r>l){
        retMod=l;
        retDiv=0;
    }else{
        copyd=r<<diffBits;
        adder=uint2048_t(1)<<diffBits;
        if(copyd>resMod){
            copyd=copyd>>1;
            adder=adder>>1;
        }
        while(resMod>=r){
            if(resMod>=copyd){
                resMod=resMod-copyd;
                resDiv=resDiv|adder;
            }
            copyd=copyd>>1;
            adder=adder>>1;
        }
        retDiv=resDiv;
        retMod=resMod;
    }
}
inline uint2048_t operator/(const uint2048_t& l,const uint2048_t& r){
    uint2048_t copyd,adder,resDiv=0,resMod=l,retDiv;
    const int diffBits=bits2048(l)-bits2048(r);
    if(r>l)retDiv=0;
    else{
        copyd=r<<diffBits;
        adder=uint2048_t(1)<<diffBits;
        if(copyd>resMod){
            copyd=copyd>>1;
            adder=adder>>1;
        }
        while(resMod>=r){
            if(resMod>=copyd){
                resMod=resMod-copyd;
                resDiv=resDiv|adder;
            }
            copyd=copyd>>1;
            adder=adder>>1;
        }
        retDiv=resDiv;
    }return retDiv;
}
inline uint2048_t operator%(const uint2048_t& l,const uint2048_t& r){return l-l/r*r;}
inline uint2048_t uint2048_t::operator+=(const uint2048_t& r){return *this=*this+r;}
inline uint2048_t uint2048_t::operator-=(const uint2048_t& r){return *this=*this-r;}
inline uint2048_t uint2048_t::operator*=(const uint2048_t& r){return *this=*this*r;}
inline uint2048_t uint2048_t::operator/=(const uint2048_t& r){return *this=*this/r;}
inline uint2048_t uint2048_t::operator%=(const uint2048_t& r){return *this=*this%r;}
inline uint2048_t uint2048_t::operator<<=(const int r){return *this=*this<<r;}
inline uint2048_t uint2048_t::operator>>=(const int r){return *this=*this>>r;}
inline uint2048_t uint2048_t::operator&=(const uint2048_t& r){return *this=*this&r;}
inline uint2048_t uint2048_t::operator|=(const uint2048_t& r){return *this=*this&r;}
inline void tostring2048(const uint2048_t& number,const unsigned char base,char *out,unsigned long long outLength){
    uint2048_t rDiv=number,rMod=0;
    unsigned long long offset=0;
    if(base<2||base>36)return;
    do{
        if(offset>outLength-1)return;
        divmod2048(rDiv,base,rDiv,rMod);
        out[offset++]=HEXDIGITS[rMod.low.low.low];
    }while(!zero2048(rDiv));
    out[offset]=0;
    reverseString(out,offset);
}
inline void tostring2048_upper(uint2048_t& number,const unsigned char base,char *out,unsigned long long outLength){
    uint2048_t rDiv=number,rMod=0;
    unsigned long long offset=0;
    if(base<2||base>36)return;
    do{
        if(offset>outLength-1)return;
        divmod2048(rDiv,base,rDiv,rMod);
        out[offset++]=HEXDIGITSUPPER[rMod.low.low.low];
    }while(!zero2048(rDiv));
    out[offset]=0;
    reverseString(out,offset);
}
inline void tostring2048(uint2048_t& number,const unsigned char base,char *out,unsigned long long outLength,const char* BaseMap){
    uint2048_t rDiv=number,rMod=0;
    unsigned long long offset=0;
    if(base<2||base>36)return;
    do{
        if(offset>outLength-1)return;
        divmod2048(rDiv,base,rDiv,rMod);
        out[offset++]=BaseMap[rMod.low.low.low];
    }while(!zero2048(rDiv));
    out[offset]=0;
    reverseString(out,offset);
}
inline char* uint2048_t::c_str(){
    static char Str[640];
    tostring2048(*this,10,Str,640);
    return Str;
}
main(){
    uint2048_t a,b;
    char A[501],B[501];
    scanf("%s%s",A,B);
    for(int i=0;A[i];++i)a=(a<<1)+(a<<3)+(A[i]^48);
    for(int i=0;B[i];++i)b=(b<<1)+(b<<3)+(B[i]^48);
    puts((a+b).c_str());
}

by Little_Cabbage @ 2023-06-27 20:46:18


上一页 |