• 大数模板


      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)
  • 相关阅读:
    无尽的冒险
    推荐一款好用的markdown编辑器,还可以引入vue主题
    你是微光
    Echarts 空心饼图示例
    vue + element-ui 制作tab切换(切换vue组件,踩坑总结)
    vue + element-ui 制作tab切换(适用于单页切换不同标记显示不同内容)
    Element UI 封装Table --> 实现动态创建表头和单元格数据(单元格内可动态增加非纯文本的内容)
    Element UI 封装Table --> 实现动态创建表头和单元格数据(无需写死表头和单元格数据)
    vue 部署到生产出现语法错误和css警告(Resource interpreted as Stylesheet but transferred with MIME type text/html: "www.aaa.com/cal/static/css/app.c06.css". vendor.4b6.js:1 Uncaught SyntaxError: Unexpected token '<')
    使用vue-cookies插件操作cookie
  • 原文地址:https://www.cnblogs.com/sanghai/p/3091632.html
Copyright © 2020-2023  润新知