大数模板

  1 #include<iostream>
  2 #include<string>
  3 #include<iomanip>
  4 #include<algorithm>
  5 using namespace std;
  6 
  7 #define MAXN 9999
  8 #define MAXSIZE 10
  9 #define DLEN 4
 10 
 11 class BigNum
 12 {
 13 private:
 14     int a[500];    //可以控制大数的位数
 15     int len;       //大数长度
 16 public:
 17     BigNum()
 18     {
 19         len = 1;    //构造函数
 20         memset(a,0,sizeof(a));
 21     }
 22     BigNum(const int);       //将一个int类型的变量转化为大数
 23     BigNum(const char*);     //将一个字符串类型的变量转化为大数
 24     BigNum(const BigNum &);  //拷贝构造函数
 25     BigNum &operator=(const BigNum &);   //重载赋值运算符,大数之间进行赋值运算
 26 
 27     friend istream& operator>>(istream&,  BigNum&);   //重载输入运算符
 28     friend ostream& operator<<(ostream&,  BigNum&);   //重载输出运算符
 29 
 30     BigNum operator+(const BigNum &) const;   //重载加法运算符,两个大数之间的相加运算
 31     BigNum operator-(const BigNum &) const;   //重载减法运算符,两个大数之间的相减运算
 32     BigNum operator*(const BigNum &) const;   //重载乘法运算符,两个大数之间的相乘运算
 33     BigNum operator/(const int   &) const;    //重载除法运算符,大数对一个整数进行相除运算
 34 
 35     BigNum operator^(const int  &) const;    //大数的n次方运算
 36     int    operator%(const int  &) const;    //大数对一个int类型的变量进行取模运算
 37     bool   operator>(const BigNum & T)const;   //大数和另一个大数的大小比较
 38     bool   operator>(const int & t)const;      //大数和一个int类型的变量的大小比较
 39 
 40     void print();       //输出大数
 41 };
 42 BigNum::BigNum(const int b)     //将一个int类型的变量转化为大数
 43 {
 44     int c,d = b;
 45     len = 0;
 46     memset(a,0,sizeof(a));
 47     while(d > MAXN)
 48     {
 49         c = d - (d / (MAXN + 1)) * (MAXN + 1);
 50         d = d / (MAXN + 1);
 51         a[len++] = c;
 52     }
 53     a[len++] = d;
 54 }
 55 BigNum::BigNum(const char*s)     //将一个字符串类型的变量转化为大数
 56 {
 57     int t,k,index,l,i;
 58     memset(a,0,sizeof(a));
 59     l=strlen(s);
 60     len=l/DLEN;
 61     if(l%DLEN)
 62         len++;
 63     index=0;
 64     for(i=l-1; i>=0; i-=DLEN)
 65     {
 66         t=0;
 67         k=i-DLEN+1;
 68         if(k<0)
 69             k=0;
 70         for(int j=k; j<=i; j++)
 71             t=t*10+s[j]-'0';
 72         a[index++]=t;
 73     }
 74 }
 75 BigNum::BigNum(const BigNum & T) : len(T.len)  //拷贝构造函数
 76 {
 77     int i;
 78     memset(a,0,sizeof(a));
 79     for(i = 0 ; i < len ; i++)
 80         a[i] = T.a[i];
 81 }
 82 BigNum & BigNum::operator=(const BigNum & n)   //重载赋值运算符,大数之间进行赋值运算
 83 {
 84     int i;
 85     len = n.len;
 86     memset(a,0,sizeof(a));
 87     for(i = 0 ; i < len ; i++)
 88         a[i] = n.a[i];
 89     return *this;
 90 }
 91 istream& operator>>(istream & in,  BigNum & b)   //重载输入运算符
 92 {
 93     char ch[MAXSIZE*4];
 94     int i = -1;
 95     in>>ch;
 96     int l=strlen(ch);
 97     int count=0,sum=0;
 98     for(i=l-1; i>=0;)
 99     {
100         sum = 0;
101         int t=1;
102         for(int j=0; j<4&&i>=0; j++,i--,t*=10)
103         {
104             sum+=(ch[i]-'0')*t;
105         }
106         b.a[count]=sum;
107         count++;
108     }
109     b.len =count++;
110     return in;
111 
112 }
113 ostream& operator<<(ostream& out,  BigNum& b)   //重载输出运算符
114 {
115     int i;
116     cout << b.a[b.len - 1];
117     for(i = b.len - 2 ; i >= 0 ; i--)
118     {
119         cout.width(DLEN);
120         cout.fill('0');
121         cout << b.a[i];
122     }
123     return out;
124 }
125 
126 BigNum BigNum::operator+(const BigNum & T) const   //两个大数之间的相加运算
127 {
128     BigNum t(*this);
129     int i,big;      //位数
130     big = T.len > len ? T.len : len;
131     for(i = 0 ; i < big ; i++)
132     {
133         t.a[i] +=T.a[i];
134         if(t.a[i] > MAXN)
135         {
136             t.a[i + 1]++;
137             t.a[i] -=MAXN+1;
138         }
139     }
140     if(t.a[big] != 0)
141         t.len = big + 1;
142     else
143         t.len = big;
144     return t;
145 }
146 BigNum BigNum::operator-(const BigNum & T) const   //两个大数之间的相减运算
147 {
148     int i,j,big;
149     bool flag;
150     BigNum t1,t2;
151     if(*this>T)
152     {
153         t1=*this;
154         t2=T;
155         flag=0;
156     }
157     else
158     {
159         t1=T;
160         t2=*this;
161         flag=1;
162     }
163     big=t1.len;
164     for(i = 0 ; i < big ; i++)
165     {
166         if(t1.a[i] < t2.a[i])
167         {
168             j = i + 1;
169             while(t1.a[j] == 0)
170                 j++;
171             t1.a[j--]--;
172             while(j > i)
173                 t1.a[j--] += MAXN;
174             t1.a[i] += MAXN + 1 - t2.a[i];
175         }
176         else
177             t1.a[i] -= t2.a[i];
178     }
179     t1.len = big;
180     while(t1.a[len - 1] == 0 && t1.len > 1)
181     {
182         t1.len--;
183         big--;
184     }
185     if(flag)
186         t1.a[big-1]=0-t1.a[big-1];
187     return t1;
188 }
189 
190 BigNum BigNum::operator*(const BigNum & T) const   //两个大数之间的相乘运算
191 {
192     BigNum ret;
193     int i,j,up;
194     int temp,temp1;
195     for(i = 0 ; i < len ; i++)
196     {
197         up = 0;
198         for(j = 0 ; j < T.len ; j++)
199         {
200             temp = a[i] * T.a[j] + ret.a[i + j] + up;
201             if(temp > MAXN)
202             {
203                 temp1 = temp - temp / (MAXN + 1) * (MAXN + 1);
204                 up = temp / (MAXN + 1);
205                 ret.a[i + j] = temp1;
206             }
207             else
208             {
209                 up = 0;
210                 ret.a[i + j] = temp;
211             }
212         }
213         if(up != 0)
214             ret.a[i + j] = up;
215     }
216     ret.len = i + j;
217     while(ret.a[ret.len - 1] == 0 && ret.len > 1)
218         ret.len--;
219     return ret;
220 }
221 BigNum BigNum::operator/(const int & b) const   //大数对一个整数进行相除运算
222 {
223     BigNum ret;
224     int i,down = 0;
225     for(i = len - 1 ; i >= 0 ; i--)
226     {
227         ret.a[i] = (a[i] + down * (MAXN + 1)) / b;
228         down = a[i] + down * (MAXN + 1) - ret.a[i] * b;
229     }
230     ret.len = len;
231     while(ret.a[ret.len - 1] == 0 && ret.len > 1)
232         ret.len--;
233     return ret;
234 }
235 int BigNum::operator %(const int & b) const    //大数对一个int类型的变量进行取模运算
236 {
237     int i,d=0;
238     for (i = len-1; i>=0; i--)
239     {
240         d = ((d * (MAXN+1))% b + a[i])% b;
241     }
242     return d;
243 }
244 BigNum BigNum::operator^(const int & n) const    //大数的n次方运算
245 {
246     BigNum t,ret(1);
247     int i;
248     if(n<0)
249         exit(-1);
250     if(n==0)
251         return 1;
252     if(n==1)
253         return *this;
254     int m=n;
255     while(m>1)
256     {
257         t=*this;
258         for( i=1; i<<1<=m; i<<=1)
259         {
260             t=t*t;
261         }
262         m-=i;
263         ret=ret*t;
264         if(m==1)
265             ret=ret*(*this);
266     }
267     return ret;
268 }
269 bool BigNum::operator>(const BigNum & T) const   //大数和另一个大数的大小比较
270 {
271     int ln;
272     if(len > T.len)
273         return true;
274     else if(len == T.len)
275     {
276         ln = len - 1;
277         while(a[ln] == T.a[ln] && ln >= 0)
278             ln--;
279         if(ln >= 0 && a[ln] > T.a[ln])
280             return true;
281         else
282             return false;
283     }
284     else
285         return false;
286 }
287 bool BigNum::operator >(const int & t) const    //大数和一个int类型的变量的大小比较
288 {
289     BigNum b(t);
290     return *this>b;
291 }
292 
293 void BigNum::print()    //输出大数
294 {
295     int i;
296     cout << a[len - 1];
297     for(i = len - 2 ; i >= 0 ; i--)
298     {
299         cout.width(DLEN);
300         cout.fill('0');
301         cout << a[i];
302     }
303     cout << endl;
304 }
305 int main(void)
306 {
307     int i,n;
308     BigNum x[101];      //定义大数的对象数组
309     x[0]=1;
310     for(i=1; i<101; i++)
311         x[i]=x[i-1]*(4*i-2)/(i+1);
312     while(scanf("%d",&n)==1 && n!=-1)
313     {
314         x[n].print();
315     }
316 }
大数模板


关于取模运算:

取模运算的性质:(1)(a+b)%c=(a%c+b%c)%c,(2)(ab)%c=(a%c)(b%c)%c。所以可以拆成一系列加数的和,和一系列数的积。先用(1)再用(2)。如100003003=100000000+3000+3,100000000=10×10×10×10×10×10×10×10。。。。所以要存储从10到10000....0000对那个数的模,这个存储的过程是个一阶循环,与这个数的位数有关。再看大数的那一位不是0,再用性质(2)。我没有做这个题,这个理论应该没错。给我评个好,哈哈哈

 

以下是百度百科:

基本性质:
(1)若p|(a-b),则a≡b (% p)。例如 11 ≡ 4 (% 7), 18 ≡ 4(% 7)
(2)(a % p)=(b % p)意味a≡b (% p)
(3)对称性:a≡b (% p)等价于b≡a (% p)
(4)传递性:若a≡b (% p)且b≡c (% p) ,则a≡c (% p)
运算规则:
模运算与基本四则运算有些相似,但是除法例外。其规则如下:
(a + b) % p = (a % p + b % p) % p (1)
(a - b) % p = (a % p - b % p) % p (2)
(a * b) % p = (a % p * b % p) % p (3)
ab % p = ((a % p)b) % p (4)
结合律: ((a+b) % p + c) % p = (a + (b+c) % p) % p (5)
((a*b) % p * c)% p = (a * (b*c) % p) % p (6)
交换律: (a + b) % p = (b+a) % p (7)
(a * b) % p = (b * a) % p (8)
分配律: ((a +b)% p * c) % p = ((a * c) % p + (b * c) % p) % p (9)
重要定理:若a≡b (% p),则对于任意的c,都有(a + c) ≡ (b + c) (%p);(10)
若a≡b (% p),则对于任意的c,都有(a * c) ≡ (b * c) (%p);(11)
若a≡b (% p),c≡d (% p),则 (a + c) ≡ (b + d) (%p),(a - c) ≡ (b - d) (%p),
(a * c) ≡ (b * d) (%p),(a / c) ≡ (b / d) (%p); (12)
若a≡b (% p),则对于任意的c,都有ac≡ bc (%p); (13)
posted on 2013-05-21 21:36 桑海 阅读( ...) 评论( ...) 编辑 收藏

转载于:https://www.cnblogs.com/sanghai/archive/2013/05/21/3091632.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值