• 高精模板


    前言

    今天遇到了一道非常恶心的区间DP题 【P1005 矩阵取数游戏】。

    本身是一道很简单的区间DP问题。但是数据范围:

    (60\%) 的数据满足:(1le n,mle 30),答案不超过 (10^{16})

    (100\%) 的数据满足:(1le n,mle 80)(0le a_{i,j}le1000)

    对于剩下(40\%)的数据,需要使用高精。

    由于懒得次次都手写高精,于是有此模板。

    这篇博客,理论上是会随着学习的深入更新的!

    模板

    高精度算法(High Accuracy Algorithm)是处理大数字的数学计算方法。

    这里使用了压位高精。(既然写了高精就要让他做到最好!)

    经极其不完全统计,压位高精取(10^7)进制时较快。

    总模板(直接复制这里)

    const int bse = 1e7;
    struct haa{
    	ll a[105];int len;
    	haa(){len = 1, memset(a,0,sizeof(a));}
    	haa(int x){
            memset(a,0,sizeof(a));len = 1;
            while(x){a[len++] = x % bse,x /= bse;}len --;
        }
    	void print(){
            printf("%lld",a[len]);
            for(int i = len-1 ; i ; i --)printf("%07lld",a[i]);
        }
    }; 
    haa operator + (haa& a,haa& b){
    	haa ret = 0; ret.len = max(a.len,b.len) + 1;
    	for(int i = 1 ; i <= ret.len ; i ++)
    		ret.a[i] += a.a[i] + b.a[i],
    		ret.a[i+1] += ret.a[i] / bse,
    		ret.a[i] %= bse;
    	for(int i = 1 ; i <= ret.len ; i ++)
    		ret.a[i+1] += ret.a[i] / bse,
    		ret.a[i] %= bse;
    	while(ret.len > 1 && !ret.a[ret.len]) ret.len --;
    	return ret;
    }
    haa operator * (haa& a,haa& b){
    	haa ret = 0; ret.len = a.len + b.len + 1;
    	for(int i = 1 ; i <= a.len ; i ++)
    		for(int j = 1 ; j <= b.len ; j ++)
    			ret.a[i+j-1] += a.a[i] * b.a[j],
    			ret.a[i+j] += ret.a[i+j-1] / bse,
    			ret.a[i+j-1] %= bse;
    	for(int i = 1 ; i <= ret.len ; i ++)
    		ret.a[i+1] += ret.a[i] / bse ,
    		ret.a[i] %= bse;
    	while(ret.len > 1 && !ret.a[ret.len]) ret.len --;
    	return ret;
    }
    haa operator * (haa& a,int b){
    	haa ret = 0 ; ret.len = a.len;
    	int x = b;
    	while(x) ret.len ++ , x /= bse;
    	for(int i = 1 ; i <= a.len ; i ++)
    		ret.a[i] += a.a[i] * b,
    		ret.a[i+1] += ret.a[i] / bse,
    		ret.a[i] %= bse;
    	for(int i = 1 ; i <= ret.len ; i ++)
    		ret.a[i+1] += ret.a[i] / bse,
    		ret.a[i] %= bse;
    	while(ret.len > 1 && !ret.a[ret.len]) ret.len --;
    	return ret;
    }
    inline void operator += (haa& a,haa& b){a = a+b;}
    inline void operator *= (haa& a,int b){a = a*b;}
    inline void operator *= (haa& a,haa& b){a = a*b;}
    bool operator < (const haa& a,const haa& b){
    	if(a.len != b.len) return a.len < b.len;
    	for(int i = a.len ; i ; i --)
    		if(a.a[i] != b.a[i]) return a.a[i] < b.a[i];
    	return 0;
    }
    bool operator == (const haa& a,const haa& b){
    	if(a.len != b.len) return 0;
    	for(int i = a.len ; i ; i --)
    		if(a.a[i] != b.a[i]) return 0;
    	return 1;
    }
    bool operator > (const haa& a,const haa& b){return !(a<b) && !(a == b);}
    

    以下具体说明。

    声明部分(内含构造函数及输出)

    const int bse = 1e7;//若需修改进制,修改此处即可
    struct haa{
    	ll a[105];int len;
    	haa(){len = 1, memset(a,0,sizeof(a));}
    	haa(int x){
            memset(a,0,sizeof(a));len = 1;
            while(x){a[len++] = x % bse,x /= bse;}len --;
        }
    	void print(){
            printf("%lld",a[len]);
            for(int i = len-1 ; i ; i --)printf("%07lld",a[i]);
        }
    };
    

    此时,向高精赋值可以写作:

    int x = /*...*/;
    haa a = x;
    

    或者可以写作:haa a = read();

    输出某值可以直接写成:

    haa a = /*...*/;
    a.print();
    

    高精(+)高精

    haa operator + (haa& a,haa& b){
    	haa ret = 0; ret.len = max(a.len,b.len) + 1;
    	for(int i = 1 ; i <= ret.len ; i ++)
    		ret.a[i] += a.a[i] + b.a[i],
    		ret.a[i+1] += ret.a[i] / bse,
    		ret.a[i] %= bse;
    	for(int i = 1 ; i <= ret.len ; i ++)
    		ret.a[i+1] += ret.a[i] / bse,
    		ret.a[i] %= bse;
    	while(ret.len > 1 && !ret.a[ret.len]) ret.len --;
    	return ret;
    }
    inline void operator += (haa& a,haa& b){a = a+b;}
    

    调用时,写作a = a + ba += b

    高精( imes)低精

    haa operator * (haa& a,int b){
    	haa ret = 0 ; ret.len = a.len;
    	int x = b;
    	while(x) ret.len ++ , x /= bse;
    	for(int i = 1 ; i <= a.len ; i ++)
    		ret.a[i] += a.a[i] * b,
    		ret.a[i+1] += ret.a[i] / bse,
    		ret.a[i] %= bse;
    	for(int i = 1 ; i <= ret.len ; i ++)
    		ret.a[i+1] += ret.a[i] / bse,
    		ret.a[i] %= bse;
    	while(ret.len > 1 && !ret.a[ret.len]) ret.len --;
    	return ret;
    }
    inline void operator *= (haa& a,int b){a = a*b;}
    

    调用同上。

    高精( imes)高精

    haa operator * (haa& a,haa& b){
    	haa ret = 0; ret.len = a.len + b.len + 1;
    	for(int i = 1 ; i <= a.len ; i ++)
    		for(int j = 1 ; j <= b.len ; j ++)
    			ret.a[i+j-1] += a.a[i] * b.a[j],
    			ret.a[i+j] += ret.a[i+j-1] / bse,
    			ret.a[i+j-1] %= bse;
    	for(int i = 1 ; i <= ret.len ; i ++)
    		ret.a[i+1] += ret.a[i] / bse ,
    		ret.a[i] %= bse;
    	while(ret.len > 1 && !ret.a[ret.len]) ret.len --;
    	return ret;
    }
    inline void operator *= (haa& a,haa& b){a = a*b;}
    

    调用同上。

    判断符

    bool operator < (const haa& a,const haa& b){
    	if(a.len != b.len) return a.len < b.len;
    	for(int i = a.len ; i ; i --)
    		if(a.a[i] != b.a[i]) return a.a[i] < b.a[i];
    	return 0;
    }
    bool operator == (const haa& a,const haa& b){
    	if(a.len != b.len) return 0;
    	for(int i = a.len ; i ; i --)
    		if(a.a[i] != b.a[i]) return 0;
    	return 1;
    }
    bool operator > (const haa& a,const haa& b){return !(a<b) && !(a == b);}
    

    调用同其他。

    可以直接使用(max)(min)等函数。

  • 相关阅读:
    个推微服务网关架构实践
    NB-IoT 的“前世今生”
    个推基于Consul的配置管理
    个推Node.js 微服务实践:基于容器的一站式命令行工具链
    个推用户画像的实践与应用
    TensorFlow分布式实践
    个数是如何用大数据做行为预测的?
    QCon技术干货:个推基于Docker和Kubernetes的微服务实践
    基于CMS的组件复用实践
    数据可视化:浅谈热力图如何在前端实现
  • 原文地址:https://www.cnblogs.com/Shinomiya/p/15247131.html
Copyright © 2020-2023  润新知