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)等函数。

  • 相关阅读:
    【LeetCode】3. Longest Substring Without Repeating Characters
    【LeetCode】65. Valid Number
    【LeetCode】8. String to Integer (atoi)
    【Java】 大话数据结构(18) 排序算法(5) (直接插入排序)
    【LeetCode】557. Reverse Words in a String III
    【LeetCode】151. Reverse Words in a String
    【LeetCode】28. Implement strStr()
    【LeetCode】125. Valid Palindrome
    【Java】 遍历HashMap
    【LeetCode】170. Two Sum III – Data structure design
  • 原文地址:https://www.cnblogs.com/Shinomiya/p/15247131.html
Copyright © 2011-2022 走看看