大数模板 (C ++)
上次BC遇到一个大数题目,没有大数模板和不会使用JAVA的同学们GG了,赛后从队友哪里骗出大数模板。2333333,真的炒鸡nice(就是有点长),贴出来分享一下好辣。
- //可以处理字符串前导零
- #include <iostream>
- #include <queue>
- #include <cstdio>
- #include <cstring>
- #include <cstdlib>
- #include <stack>
- using namespace std;
- #define maxn 120//大数的个数
- class DividedByZeroException {};
- class BigInteger
- {
- private:
- vector<char> digits;
- bool sign; // true for positive, false for negitive
- void trim(); // remove zeros in tail, but if the value is 0, keep only one:)
- public:
- BigInteger(int); // construct with a int integer
- BigInteger(string&) ;
- BigInteger();
- BigInteger (const BigInteger&);
- BigInteger operator=(const BigInteger& op2);
- BigInteger abs() const;
- BigInteger pow(int a);
- //binary operators
- friend BigInteger operator+=(BigInteger&,const BigInteger&);
- friend BigInteger operator-=(BigInteger&,const BigInteger&);
- friend BigInteger operator*=(BigInteger&,const BigInteger&);
- friend BigInteger operator/=(BigInteger&,const BigInteger&) throw(DividedByZeroException);
- friend BigInteger operator%=(BigInteger&,const BigInteger&) throw(DividedByZeroException);
- friend BigInteger operator+(const BigInteger&,const BigInteger&);
- friend BigInteger operator-(const BigInteger&,const BigInteger&);
- friend BigInteger operator*(const BigInteger&,const BigInteger&);
- friend BigInteger operator/(const BigInteger&,const BigInteger&) throw(DividedByZeroException);
- friend BigInteger operator%(const BigInteger&,const BigInteger&) throw(DividedByZeroException);
- //uniary operators
- friend BigInteger operator-(const BigInteger&); //negative
- friend BigInteger operator++(BigInteger&); //++v
- friend BigInteger operator++(BigInteger&,int); //v++
- friend BigInteger operator--(BigInteger&); //--v
- friend BigInteger operator--(BigInteger&,int); //v--
- friend bool operator>(const BigInteger&,const BigInteger&);
- friend bool operator<(const BigInteger&,const BigInteger&);
- friend bool operator==(const BigInteger&,const BigInteger&);
- friend bool operator!=(const BigInteger&,const BigInteger&);
- friend bool operator>=(const BigInteger&,const BigInteger&);
- friend bool operator<=(const BigInteger&,const BigInteger&);
- friend ostream& operator<<(ostream&,const BigInteger&); //print the BigInteger
- friend istream& operator>>(istream&, BigInteger&); // input the BigInteger
- public:
- static const BigInteger ZERO;
- static const BigInteger ONE;
- static const BigInteger TEN;
- };
- // BigInteger.cpp
- const BigInteger BigInteger::ZERO=BigInteger();
- const BigInteger BigInteger::ONE =BigInteger();
- const BigInteger BigInteger::TEN =BigInteger();
- BigInteger::BigInteger()
- {
- sign=true;
- }
- BigInteger::BigInteger(int val) // construct with a int integer
- {
- if (val >= )
- sign = true;
- else
- {
- sign = false;
- val *= (-);
- }
- do
- {
- digits.push_back( (char)(val%) );
- val /= ;
- }
- while ( val != );
- }
- BigInteger::BigInteger(string& def)
- {
- sign=true;
- for ( string::reverse_iterator iter = def.rbegin() ; iter < def.rend(); iter++)
- {
- char ch = (*iter);
- if (iter == def.rend()-)
- {
- if ( ch == '+' )
- break;
- if(ch == '-' )
- {
- sign = false;
- break;
- }
- }
- digits.push_back( (char)((*iter) - '' ) );
- }
- trim();
- }
- void BigInteger::trim()
- {
- vector<char>::reverse_iterator iter = digits.rbegin();
- while(!digits.empty() && (*iter) == )
- {
- digits.pop_back();
- iter=digits.rbegin();
- }
- if( digits.size()== )
- {
- sign = true;
- digits.push_back();
- }
- }
- BigInteger::BigInteger(const BigInteger& op2)
- {
- sign = op2.sign;
- digits=op2.digits;
- }
- BigInteger BigInteger::operator=(const BigInteger& op2)
- {
- digits = op2.digits;
- sign = op2.sign;
- return (*this);
- }
- BigInteger BigInteger::abs() const
- {
- if(sign) return *this;
- else return -(*this);
- }
- BigInteger BigInteger::pow(int a)
- {
- BigInteger res();
- for(int i=; i<a; i++)
- res*=(*this);
- return res;
- }
- //binary operators
- BigInteger operator+=(BigInteger& op1,const BigInteger& op2)
- {
- if( op1.sign == op2.sign )
- {
- //只处理相同的符号的情况,异号的情况给-处理
- vector<char>::iterator iter1;
- vector<char>::const_iterator iter2;
- iter1 = op1.digits.begin();
- iter2 = op2.digits.begin();
- char to_add = ; //进位
- while ( iter1 != op1.digits.end() && iter2 != op2.digits.end())
- {
- (*iter1) = (*iter1) + (*iter2) + to_add;
- to_add = ((*iter1) > ); // 大于9进一位
- (*iter1) = (*iter1) % ;
- iter1++;
- iter2++;
- }
- while ( iter1 != op1.digits.end() ) //
- {
- (*iter1) = (*iter1) + to_add;
- to_add = ( (*iter1) > );
- (*iter1) %= ;
- iter1++;
- }
- while ( iter2 != op2.digits.end() )
- {
- char val = (*iter2) + to_add;
- to_add = (val > ) ;
- val %= ;
- op1.digits.push_back(val);
- iter2++;
- }
- if( to_add != )
- op1.digits.push_back(to_add);
- return op1;
- }
- else
- {
- if (op1.sign)
- return op1 -= (-op2);
- else
- return op1= op2 - (-op1);
- }
- }
- BigInteger operator-=(BigInteger& op1,const BigInteger& op2)
- {
- if( op1.sign == op2.sign )
- {
- //只处理相同的符号的情况,异号的情况给+处理
- if(op1.sign)
- {
- if(op1 < op2) // 2 - 3
- return op1=-(op2 - op1);
- }
- else
- {
- if(-op1 > -op2) // (-3)-(-2) = -(3 - 2)
- return op1=-((-op1)-(-op2));
- else // (-2)-(-3) = 3 - 2
- return op1= (-op2) - (-op1);
- }
- vector<char>::iterator iter1;
- vector<char>::const_iterator iter2;
- iter1 = op1.digits.begin();
- iter2 = op2.digits.begin();
- char to_substract = ; //借位
- while ( iter1 != op1.digits.end() && iter2 != op2.digits.end())
- {
- (*iter1) = (*iter1) - (*iter2) - to_substract;
- to_substract = ;
- if( (*iter1) < )
- {
- to_substract=;
- (*iter1) += ;
- }
- iter1++;
- iter2++;
- }
- while ( iter1 != op1.digits.end() )
- {
- (*iter1) = (*iter1) - to_substract;
- to_substract = ;
- if( (*iter1) < )
- {
- to_substract=;
- (*iter1) += ;
- }
- else break;
- iter1++;
- }
- op1.trim();
- return op1;
- }
- else
- {
- if (op1 > BigInteger::ZERO)
- return op1 += (-op2);
- else
- return op1 = -(op2 + (-op1));
- }
- }
- BigInteger operator*=(BigInteger& op1,const BigInteger& op2)
- {
- BigInteger result();
- if (op1 == BigInteger::ZERO || op2==BigInteger::ZERO)
- result = BigInteger::ZERO;
- else
- {
- vector<char>::const_iterator iter2 = op2.digits.begin();
- while( iter2 != op2.digits.end() )
- {
- if(*iter2 != )
- {
- deque<char> temp(op1.digits.begin() , op1.digits.end());
- char to_add = ;
- deque<char>::iterator iter1 = temp.begin();
- while( iter1 != temp.end() )
- {
- (*iter1) *= (*iter2);
- (*iter1) += to_add;
- to_add = (*iter1) / ;
- (*iter1) %= ;
- iter1++;
- }
- if( to_add != )
- temp.push_back( to_add );
- int num_of_zeros = iter2 - op2.digits.begin();
- while( num_of_zeros--)
- temp.push_front();
- BigInteger temp2;
- temp2.digits.insert( temp2.digits.end() , temp.begin() , temp.end() );
- temp2.trim();
- result = result + temp2;
- }
- iter2++;
- }
- result.sign = ( (op1.sign && op2.sign) || (!op1.sign && !op2.sign) );
- }
- op1 = result;
- return op1;
- }
- BigInteger operator/=(BigInteger& op1 , const BigInteger& op2 ) throw(DividedByZeroException)
- {
- if( op2 == BigInteger::ZERO )
- throw DividedByZeroException();
- BigInteger t1 = op1.abs(), t2 = op2.abs();
- if ( t1 < t2 )
- {
- op1 = BigInteger::ZERO;
- return op1;
- }
- //现在 t1 > t2 > 0
- //只需将 t1/t2的结果交给result就可以了
- deque<char> temp;
- vector<char>::reverse_iterator iter = t1.digits.rbegin();
- BigInteger temp2();
- while( iter != t1.digits.rend() )
- {
- temp2 = temp2 * BigInteger::TEN + BigInteger( (int)(*iter) );
- char s = ;
- while( temp2 >= t2 )
- {
- temp2 = temp2 - t2;
- s = s + ;
- }
- temp.push_front( s );
- iter++;
- }
- op1.digits.clear();
- op1.digits.insert( op1.digits.end() , temp.begin() , temp.end() );
- op1.trim();
- op1.sign = ( (op1.sign && op2.sign) || (!op1.sign && !op2.sign) );
- return op1;
- }
- BigInteger operator%=(BigInteger& op1,const BigInteger& op2) throw(DividedByZeroException)
- {
- return op1 -= ((op1 / op2)*op2);
- }
- BigInteger operator+(const BigInteger& op1,const BigInteger& op2)
- {
- BigInteger temp(op1);
- temp += op2;
- return temp;
- }
- BigInteger operator-(const BigInteger& op1,const BigInteger& op2)
- {
- BigInteger temp(op1);
- temp -= op2;
- return temp;
- }
- BigInteger operator*(const BigInteger& op1,const BigInteger& op2)
- {
- BigInteger temp(op1);
- temp *= op2;
- return temp;
- }
- BigInteger operator/(const BigInteger& op1,const BigInteger& op2) throw(DividedByZeroException)
- {
- BigInteger temp(op1);
- temp /= op2;
- return temp;
- }
- BigInteger operator%(const BigInteger& op1,const BigInteger& op2) throw(DividedByZeroException)
- {
- BigInteger temp(op1);
- temp %= op2;
- return temp;
- }
- //uniary operators
- BigInteger operator-(const BigInteger& op) //negative
- {
- BigInteger temp = BigInteger(op);
- temp.sign = !temp.sign;
- return temp;
- }
- BigInteger operator++(BigInteger& op) //++v
- {
- op += BigInteger::ONE;
- return op;
- }
- BigInteger operator++(BigInteger& op,int x) //v++
- {
- BigInteger temp(op);
- ++op;
- return temp;
- }
- BigInteger operator--(BigInteger& op) //--v
- {
- op -= BigInteger::ONE;
- return op;
- }
- BigInteger operator--(BigInteger& op,int x) //v--
- {
- BigInteger temp(op);
- --op;
- return temp;
- }
- bool operator<(const BigInteger& op1,const BigInteger& op2)
- {
- if( op1.sign != op2.sign )
- return !op1.sign;
- else
- {
- if(op1.digits.size() != op2.digits.size())
- return (op1.sign && op1.digits.size()<op2.digits.size())
- || (!op1.sign && op1.digits.size()>op2.digits.size());
- vector<char>::const_reverse_iterator iter1,iter2;
- iter1 = op1.digits.rbegin();
- iter2 = op2.digits.rbegin();
- while( iter1 != op1.digits.rend() )
- {
- if( op1.sign && *iter1 < *iter2 ) return true;
- if( op1.sign && *iter1 > *iter2 ) return false;
- if( !op1.sign && *iter1 > *iter2 ) return true;
- if( !op1.sign && *iter1 < *iter2 ) return false;
- iter1++;
- iter2++;
- }
- return false;
- }
- }
- bool operator==(const BigInteger& op1,const BigInteger& op2)
- {
- if( op1.sign != op2.sign || op1.digits.size() != op2.digits.size() )
- return false;
- vector<char>::const_iterator iter1,iter2;
- iter1 = op1.digits.begin();
- iter2 = op2.digits.begin();
- while( iter1!= op1.digits.end() )
- {
- if( *iter1 != *iter2 ) return false;
- iter1++;
- iter2++;
- }
- return true;
- }
- bool operator!=(const BigInteger& op1,const BigInteger& op2)
- {
- return !(op1==op2);
- }
- bool operator>=(const BigInteger& op1,const BigInteger& op2)
- {
- return (op1>op2) || (op1==op2);
- }
- bool operator<=(const BigInteger& op1,const BigInteger& op2)
- {
- return (op1<op2) || (op1==op2);
- }
- bool operator>(const BigInteger& op1,const BigInteger& op2)
- {
- return !(op1<=op2);
- }
- ostream& operator<<(ostream& stream,const BigInteger& val) //print the BigInteger
- {
- if (!val.sign)
- stream << "-";
- for ( vector<char>::const_reverse_iterator iter = val.digits.rbegin(); iter != val.digits.rend() ; iter++)
- stream << (char)((*iter) + '');
- return stream;
- }
- istream& operator>>(istream& stream, BigInteger& val)
- {
- //Input the BigInteger
- string str;
- stream >> str;
- val=BigInteger(str);
- return stream;
- }
- BigInteger a;
- //定义一个大数a
在Hdu上要用G++提交,C++提交会CE,亲测!!!!
大数模板 (C ++)的更多相关文章
- bignum 大数模板
今天无意间看到一个很好的大数模板,能算加.减.乘.除等基本运算,但操作减法的时候只能大数减小数,也不支持负数,如果是两个负数的话去掉符号相加之后再取反就可以了,一正一负比较绝对值大小,然后相减.我借用 ...
- c++大数模板
自己写的大数模板,参考了小白书上的写法,只是实现了加减乘法,不支持负数,浮点数.. 除法还没写o(╯□╰)o以后再慢慢更吧.. 其实除法我用(xie)的(bu)少(lai),乘法写过fft,这模板还是 ...
- hdu 5429 Geometric Progression(存个大数模板)
Problem Description Determine whether a sequence is a Geometric progression or not. In mathematics, ...
- ACM大数模板(支持正负整数)
之前就保留过简陋的几个用外部数组变量实现的简单大数模板,也没有怎么用过,今天就想着整合封装一下,封装成C++的类,以后需要调用的时候也方便得多. 实现了基本的加减乘除和取模运算的操作符重载,大数除以大 ...
- 【集训笔记】【大数模板】特殊的数 【Catalan数】【HDOJ1133【HDOJ1134【HDOJ1130
http://acm.zju.edu.cn/onlinejudge/showProblem.do?problemCode=3324 http://blog.csdn.net/xymscau/artic ...
- hdu1042(大数模板)
题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=1042 在网上找了个大数模板方便以后用得到. #include<iostream> #inc ...
- 大数模板 poj3982
1. 这个模板不是自己写的,转载的别人转载的,还没学完c++的我,想写也没有那能力. 这个模板我用在了POJ的一道题上,传送门--POJ3982 一般大数的题,都可用这个模板解决,仅仅须要改动主函数就 ...
- Hdu 4762 网络赛 高精度大数模板+概率
注意题目中的这句话he put the strawberries on the cake randomly one by one,第一次选择草莓其实有N个可能,以某一个草莓为开头,然后顺序的随机摆放, ...
- vijos - P1447开关灯泡 (大数模板 + 找规律 + 全然数 + python)
P1447开关灯泡 Accepted 标签:CSC WorkGroup III[显示标签] 描写叙述 一个房间里有n盏灯泡.一開始都是熄着的,有1到n个时刻.每一个时刻i,我们会将i的倍数的灯泡改变状 ...
随机推荐
- 李洪强iOS开发之-实现点击单行View显示和隐藏Cell
李洪强iOS开发之-实现点击单行View显示和隐藏Cell 实现的效果: .... ....
- chrome自带的调试工具
由于项目需要加载webgl对浏览器内存压力很大,需要优化内存,网上找了一下资料,极力推荐chrome的开发文档 https://developers.google.cn/web/tools/chrom ...
- Session 钝化机制
- 0mq
- CentOS 7.2 安装Gerrit 2.14.6
1.环境 本文使用VMWare虚拟机进行实验. 2核CPU,4GB内存,20GB硬盘,IP:192.168.159.131 CentOS 7.2最小安装(CentOS-7-x86_64-Minimal ...
- UVA-11082 Matrix Decompressing(有上下界的最大流)
题目链接: Matrix Decompressing 题意: 给一个矩阵的每行和每列的和,(给的是前i行或者列的和); 矩阵中每个元素的值在1到20之间,找出这样的一个矩阵: 思路: 把它转化成一个二 ...
- web自动化测试的自身特点
1.web页面是出现的元素可能具有不确定性 2.不同操作系统上不同web浏览器之间的兼容性 3.web应用的高并发性和容错性 4.移动设备上web客户端兼容性,旋转下和各种触摸特性
- macbook pro 下eclipse配置svn插件
eclipse中最常使用的SVN插件是subclipse,先到subclipse官网:http://subclipse.tigris.org下载该插件. 如上图,点击“Download and I ...
- TCP连接、释放及HTTPS连接流程
一.建立连接是三次握手 为什么三次握手?前两次握手为了确认服务端能正常收到客户端的请求并愿意应答,后两次握手是为了确认客户端能正常收到服务端的请求并愿意应答.三次握手可以避免意外建立错误连接而导致浪费 ...
- bzoj1925地精部落——数学
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1925 真是精妙的递推式...好难想到啊: 详见这位的博客:https://www.cnblo ...