首页 > 其他分享 >压位高精度模板

压位高精度模板

时间:2022-11-15 23:12:38浏览次数:68  
标签:__ const 高精度 压位 int256 len ans return 模板

压位高精全家桶。

原代码来自于知乎上人形魔芋的压位高精模板,进行了一些修改和改进。

namespace BigInteger
{
    typedef long long ll;
    typedef unsigned long long ull;
    class __int256
    {
    private:
        const static int N=3005,base=1e8;
        int a[N],len,neg;
        void write(int _a)const{if(_a>9)write(_a/10);putchar((_a%10)|48);}
        int getlen(int _a)const{int ans=0;while(_a)_a/=10,++ans;return ans;}
    public:
        __int256(){len=1,neg=0,memset(a,0,sizeof(a));}
        __int256(char *s)
        {
            memset(a,0,sizeof(a));
            if(s[0]=='-')
            {
                int slen=strlen(s)-1;
                len=1,neg=1;
                int k=1;
                for(int i=1;i<=slen;++i)
                {
                    if(k==base)++len,k=1;
                    a[len]+=k*(s[slen-i+1]^48);
                    k*=10;
                }
            }
            else
            {
                int slen=strlen(s);
                len=1,neg=0;
                int k=1;
                for(int i=1;i<=slen;++i)
                {
                    if(k==base)++len,k=1;
                    a[len]+=k*(s[slen-i]^48);
                    k*=10;
                }
            }
        }
        __int256(std::string s)
        {
            memset(a,0,sizeof(a));
            if(s[0]=='-')
            {
                int slen=s.size()-1;
                len=1,neg=1;
                int k=1;
                for(int i=1;i<=slen;++i)
                {
                    if(k==base)++len,k=1;
                    a[len]+=k*(s[slen-i+1]^48);
                    k*=10;
                }
            }
            else
            {
                int slen=s.size();
                len=1,neg=0;
                int k=1;
                for(int i=1;i<=slen;++i)
                {
                    if(k==base)++len,k=1;
                    a[len]+=k*(s[slen-i]^48);
                    k*=10;
                }
            }
        }
        __int256(const char *s)
        {
            memset(a,0,sizeof(a));
            if(s[0]=='-')
            {
                int slen=strlen(s)-1;
                len=1,neg=1;
                int k=1;
                for(int i=1;i<=slen;++i)
                {
                    if(k==base)++len,k=1;
                    a[len]+=k*(s[slen-i+1]^48);
                    k*=10;
                }
            }
            else
            {
                int slen=strlen(s);
                len=1,neg=0;
                int k=1;
                for(int i=1;i<=slen;++i)
                {
                    if(k==base)++len,k=1;
                    a[len]+=k*(s[slen-i]^48);
                    k*=10;
                }
            }
        }
        template<typename _Tp>__int256(_Tp x)
        {
            len=0;neg=0;
            memset(a,0,sizeof(a));
            if(x<0)x=-x,neg=1;
            int tmp;
            while((tmp=x/base))
            {
                a[++len]=x%base;
                x=tmp;
            }a[++len]=x;
        }
        void get()
        {
            std::string s=std::string();
            char ch=getchar();
            while(ch<'0'||ch>'9')
            {
                if(ch=='-'&&!s.size())s+='-';
                ch=getchar();
            }
            while(ch>='0'&&ch<='9')s+=ch,ch=getchar();
            *this=__int256(s);
        }
        void print()const
        {
            int baselen=getlen(base)-1;
            if(neg)putchar('-');
            write(a[len]);
            for(int i=len-1,tmp;i;--i)
            {
                tmp=baselen-getlen(a[i]);
                while(tmp--)putchar('0');
                if(a[i])write(a[i]);
            }
        }
        std::string to_string()
        {
            std::string res="";
            int baselen=getlen(base)-1;
            if(neg)res+="-";
            std::string tmp1="";int tmp2=a[len];
            if(!a[len])return "0";
            while(tmp2)tmp1+=tmp2%10+'0',tmp2/=10;
            reverse(tmp1.begin(),tmp1.end());res+=tmp1;
            for(int i=len-1,tmp;i;--i)
            {
                tmp=baselen-getlen(a[i]);
                while(tmp--)res+="0";
                if(!a[i])continue;
                tmp1="";tmp2=a[i];
                while(tmp2)tmp1+=tmp2%10+'0',tmp2/=10;
                reverse(tmp1.begin(),tmp1.end());res+=tmp1;
            }return res;
        }
        friend std::istream& operator>>(std::istream& input,__int256& x)
        {
            x.get();
            return input;
        }
        friend std::ostream& operator<<(std::ostream& output,const __int256& x)
        {
            x.print();
            return output;
        }
        bool operator==(const __int256& x)const
        {
            if(len!=x.len||neg!=x.neg)return false;
            for(int i=1;i<=len;++i)if(a[i]!=x.a[i])return false;
            return true;
        }
        bool operator!=(const __int256& x)const{return !(*this==x);}
        bool operator>(const __int256& x)const
        {
            if(neg!=x.neg)return x.neg;
            if(len!=x.len)return len>x.len;
            for(int i=len;i;--i)if(a[i]!=x.a[i])return a[i]>x.a[i];
            return false;
        }
        bool operator<(const __int256& x)const
        {
            if(neg!=x.neg)return neg;
            if(len!=x.len)return len<x.len;
            for(int i=len;i;--i)if(a[i]!=x.a[i])return a[i]<x.a[i];
            return false;
        }
        bool operator>=(const __int256& x)const{return !(*this<x);}
        bool operator<=(const __int256& x)const{return !(*this>x);}
        __int256 operator-()const{__int256 x(*this);x.neg^=1;return x;}
        __int256 operator+(const __int256& x)const
        {
            if((!neg)&&x.neg)return *this-(-x);
            if(neg&&(!x.neg))return x-(-*this);
            __int256 ans=__int256();
            ans.len=std::max(len,x.len);
            for(int i=1;i<=ans.len;++i)
            {
                ans.a[i]+=a[i]+x.a[i];
                if(ans.a[i]>=base)ans.a[i]-=base,++ans.a[i+1];
            }if(ans.a[ans.len+1])++ans.len;
            if(neg&&x.neg)ans.neg=1;
            return ans;
        }
        __int256 operator+=(const __int256& x){return *this=*this+x;}
        __int256 operator-(const __int256& x)const 
        {
            if((!neg)&&x.neg)return *this+(-x);
            if(neg&&x.neg)return (-x)-(-*this);
            if(neg&&(!x.neg))return -((-*this)+x);
            __int256 ans=__int256();
            if(*this==x)return ans;
            if(x>*this)
            {
                ans=(x-*this);
                ans.neg=1;
                return ans;
            }
            ans.len=std::max(len,x.len);
            for(int i=1;i<=ans.len;++i)
            {
                ans.a[i]+=a[i]-x.a[i];
                if(ans.a[i]<0)ans.a[i]+=base,--ans.a[i+1];
            }while(ans.len&&!ans.a[ans.len])--ans.len;
            return ans;
        }
        __int256 operator-=(const __int256& x){return *this=*this-x;}
        __int256 operator*(const __int256& x)const
        {

            __int256 ans=__int256();
            if(*this==ans||x==ans)return ans;
            if(neg!=x.neg)ans.neg=1;
            ans.len=len+x.len;
            ull tmp;
            for(int i=1;i<=len;++i)
                for(int j=1;j<=x.len;++j)
	            {
	                tmp=1ull*a[i]*x.a[j]+ans.a[i+j-1];
	                if(tmp>=base)
	                {
	                    ans.a[i+j]+=tmp/base;
	                    ans.a[i+j-1]=tmp%base;
	                }else ans.a[i+j-1]=tmp;
	            }
	        while(!ans.a[ans.len])--ans.len;
            return ans;
        }
        __int256 operator*=(const __int256& x){return *this=*this*x;}
        __int256 operator/(const __int256& X)const
        {
            if(X==0)std::cerr<<"Error:divide 0\n",exit(-1);
            __int256 ans(*this),x(X),tmp(1),lt=__int256();
            if(neg!=x.neg)ans.neg=1;
            while(ans>=x) x*=2,tmp*=2;
            while(tmp.len>1||tmp.a[1])
            {
                if(ans>=x) ans-=x,lt+=tmp;
                x/=2,tmp/=2;
            }ans=lt;
            while(ans.len&&!ans.a[ans.len])--ans.len;
            if(!ans.len)return __int256();
            return ans;
        }
        __int256 operator/=(const __int256& X)
        {
            if(X==0)std::cerr<<"Error:divide 0\n",exit(-1);
            __int256 x(X),tmp(1),lt=__int256();
            if(neg!=x.neg)neg=1;
            else neg=0;
            while(*this>=x) x*=2,tmp*=2;
            while(tmp.len>1||tmp.a[1])
            {
                if(*this>=x) *this-=x,lt+=tmp;
                x/=2,tmp/=2;
            }*this=lt;
            while(len&&!a[len])--len;
            if(!len)return *this=__int256();
            return *this;
        }
        __int256 operator%(const __int256& X)const
        {
            if(X==0)std::cerr<<"Error:mod 0\n",exit(-1);
            __int256 ans(*this),x(X),tmp(1),lt=__int256();
            if(neg!=x.neg)ans.neg=1;
            while(ans>=x) x*=2,tmp*=2;
            while(tmp.len>1||tmp.a[1])
            {
                if(ans>=x) ans-=x,lt+=tmp;
                x/=2,tmp/=2;
            }return ans;
        }
        __int256 operator%=(const __int256& X)
        {
            if(X==0)std::cerr<<"Error:mod 0\n",exit(-1);
            __int256 x(X),tmp(1),lt=__int256();
            if(neg!=x.neg)neg=1;
            else neg=0;
            while(*this>=x) x*=2,tmp*=2;
            while(tmp.len>1||tmp.a[1])
            {
                if(*this>=x) *this-=x,lt+=tmp;
                x/=2,tmp/=2;
            }return *this;
        }
        template<typename _Tp>operator _Tp()const{return _Tp(a[1]);}
        template<typename _Tp>__int256 operator+(const _Tp& x)const{return *this+__int256(x);}
        template<typename _Tp>__int256 operator+=(const _Tp& x){return *this=*this+x;}
        template<typename _Tp>__int256 operator-(const _Tp& x)const{return *this-__int256(x);}
        template<typename _Tp>__int256 operator-=(const _Tp& x){return *this=*this-x;}
        template<typename _Tp>__int256 operator*(const _Tp& x)const{return *this*__int256(x);}
        template<typename _Tp>__int256 operator*=(const _Tp& x){return *this=*this*x;}
        template<typename _Tp>__int256 operator/(const _Tp& x)const
        {
            if(x==0)std::cerr<<"Error:divide 0\n",exit(-1);
            __int256 ans=__int256();
            if(len==1&&x>a[1])return ans;
            ull res=0;ans.len=len;
            if(neg!=(x<0))ans.neg=1;
            for(int i=len;i;--i)
            {
                res=res*base+a[i];
                ans.a[i]=res/x;
                res%=x;
            }
            while(ans.len>1&&!ans.a[ans.len])--ans.len;
            return ans;
        }
        template<typename _Tp>__int256 operator/=(const _Tp& x){return *this=*this/x;}
        template<typename _Tp>__int256 operator%(const _Tp& x)const
        {
            if(x==0)std::cerr<<"Error:mod 0\n",exit(-1);
            if(len==1&&x>a[1])return *this;
            ull res=0;
            for(int i=len;i;--i)
            {
                res=res*base+a[i];
                res%=x;
            }return res;
        }
        template<typename _Tp>__int256 operator%=(const _Tp& x){return *this=*this%x;}
    };
    template<typename _Tp>const __int256 operator+(const _Tp& x,const __int256& y){return __int256(x)+y;}
    template<typename _Tp>const __int256 operator-(const _Tp& x,const __int256& y){return __int256(x)-y;}
    template<typename _Tp>const __int256 operator*(const _Tp& x,const __int256& y){return __int256(x)*y;}
    template<typename _Tp>const __int256 operator/(const _Tp& x,const __int256& y){return __int256(x)/y;}
    template<typename _Tp>const __int256 operator%(const _Tp& x,const __int256& y){return __int256(x)%y;}
    __int256 gcd(__int256 x,__int256 y){while(y!=0){__int256 tmp=y;y=x%y;x=tmp;}return x;}
    template<typename _Tp>const __int256 gcd(__int256 x,_Tp y){return gcd(x,__int256(y));}
    template<typename _Tp>const __int256 gcd(_Tp x,__int256 y){return gcd(__int256(x),y);}
}

标签:__,const,高精度,压位,int256,len,ans,return,模板
From: https://www.cnblogs.com/ctldragon/p/16894400.html

相关文章

  • 一个很好用的 C++ 高精度整数板子
    点击查看代码typedeflonglongll;typedeflongdoubleld;typedefcomplex<ld>pt;constintMOD=1e9+7;constldPI=acos(-1.L);template<classT>struc......
  • 模板:4个数码管动态显示精简方法
    示例:分秒表原始方法:查看代码unsignedcharSMG[]={0x3f,0x06,0x5b,0x4f,0x66,0x6d,0x7d,0x07,0x7f,0x6f};voiddisp(unsignedintj,k){ P2=0XEF;//P24数码......
  • 势能分块模板
    分块:把n分成sqrt(n)块,中间整体修改,2边暴力修改即可,修改,查询的复杂度为3sqr(n);比线段树好写一些?当然整体的修改的时候,有时候要用lz去处理, 和势能线段树......
  • Spring Boot 导出EXCEL模板以及导入EXCEL数据(阿里Easy Excel实战)
    SpringBoot导出EXCEL模板以及导入EXCEL数据(阿里EasyExcel实战)导入pom依赖编写导出模板@ApiOperation("导出xxx模板")@GetMapping("/downTemplates")public......
  • vue源码分析-挂载流程和模板编译
    前面几节我们从newVue创建实例开始,介绍了创建实例时执行初始化流程中的重要两步,配置选项的资源合并,以及响应式系统的核心思想,数据代理。在合并章节,我们对Vue丰富的选项......
  • 信息学集训 | 17 高精度算法理论与实现2
    戳一戳!和我一起走进信息学的世界导读信息学能够有助于孩子未来工作发展,提升孩子的综合能力。这一节课是我们这一期课程的最后一节课,我们继续学习高精度算法,回顾如何高精度算......
  • 二分模板
    二分是基础算法之一,常用于答案有单调性的题目,或者穷举会超时的题目intsearch(intl,intr){while(l+1<r){intmid=l+(r-l)>>1;//防溢......
  • 前后端同构和模板渲染的区别是什么呢?
    同构渲染前端与Node端渲染共同一套JavaScript代码Node端将数据预先请求并存储在HTML上Node端的React将ComponentDidMount生命周期以前的逻辑处理完成,并执行render方法......
  • 高精度AxB
    洛谷1303#include<iostream>usingnamespacestd;constintN=50000;intarr[2*N];intaa[N];intbb[N];intmain(){stringa,b;cin>>a>>b;for(in......
  • pycharm如何自定义模板?
    按照上图箭头方向设置即可. ......