zoukankan      html  css  js  c++  java
  • 高精模板

    前言

    今天遇到了一道非常恶心的区间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)等函数。

  • 相关阅读:
    使用 requests 维持会话
    使用 requests 发送 POST 请求
    使用 requests 发送 GET 请求
    requests 安装
    使用 urllib 分析 Robots 协议
    使用 urllib 解析 URL 链接
    使用 urllib 处理 HTTP 异常
    使用 urllib 处理 Cookies 信息
    使用 urllib 设置代理服务
    按单生产程序发布
  • 原文地址:https://www.cnblogs.com/Shinomiya/p/15247131.html
Copyright © 2011-2022 走看看