Created
June 20, 2013 08:50
-
-
Save dodola/5821251 to your computer and use it in GitHub Desktop.
大数模板
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#define MAXN 9999 | |
#define DLEN 4 | |
class BigNum { | |
private: | |
int a[1000];//可以控制大数的位数 | |
int len; //大数长度 | |
public: | |
BigNum() {len = 1;memset(a,0,sizeof(a));} | |
BigNum(const int); | |
BigNum(const char*); | |
BigNum(const BigNum &); | |
BigNum &operator=(const BigNum &); | |
BigNum operator+(const BigNum &) const; | |
BigNum operator-(const BigNum &) const; | |
BigNum operator*(const BigNum &) const; | |
BigNum operator/(const int &) const; | |
BigNum operator^(const int &) const; | |
int operator%(const int &) const; | |
bool operator>(const BigNum & T)const; | |
void print(); | |
}; | |
BigNum::BigNum(const int b) { | |
int c,d = b; | |
len = 0; | |
memset(a,0,sizeof(a)); | |
while(d > MAXN) { | |
c = d - (d / (MAXN + 1)) * (MAXN + 1); | |
d = d / (MAXN + 1); a[len++] = c; | |
} | |
a[len++] = d; | |
} | |
BigNum::BigNum(const char*s) { | |
int t,k,index,l,i; | |
memset(a,0,sizeof(a)); | |
l=strlen(s); | |
len=l/DLEN; | |
if(l%DLEN)len++; | |
index=0; | |
for(i=l-1;i>=0;i-=DLEN) { | |
t=0;k=i-DLEN+1; | |
if(k<0)k=0; | |
for(int j=k;j<=i;j++) | |
t=t*10+s[j]-'0'; | |
a[index++]=t; | |
} | |
} | |
BigNum::BigNum(const BigNum & T) : len(T.len) { | |
int i; | |
memset(a,0,sizeof(a)); | |
for(i = 0 ; i < len ; i++)a[i] = T.a[i]; | |
} | |
BigNum & BigNum::operator=(const BigNum & n) { | |
len = n.len; | |
memset(a,0,sizeof(a)); | |
int i; | |
for(i = 0 ; i < len ; i++) | |
a[i] = n.a[i]; | |
return *this; | |
} | |
BigNum BigNum::operator+(const BigNum & T) const { | |
BigNum t(*this); | |
int i,big;//位数 | |
big = T.len > len ? T.len : len; | |
for(i = 0 ; i < big ; i++) { | |
t.a[i] +=T.a[i]; | |
if(t.a[i] > MAXN) { | |
t.a[i + 1]++; | |
t.a[i] -=MAXN+1; | |
} | |
} | |
if(t.a[big] != 0) t.len = big + 1; | |
else t.len = big; | |
return t; | |
} | |
BigNum BigNum::operator-(const BigNum & T) const { | |
int i,j,big; | |
bool flag; | |
BigNum t1,t2; | |
if(*this>T) { | |
t1=*this; | |
t2=T; | |
flag=0; | |
} else { | |
t1=T; | |
t2=*this; | |
flag=1; | |
} | |
big=t1.len; | |
for(i = 0 ; i < big ; i++) { | |
if(t1.a[i] < t2.a[i]) { | |
j = i + 1; | |
while(t1.a[j] == 0) j++; | |
t1.a[j--]--; | |
while(j > i) t1.a[j--] += MAXN; | |
t1.a[i] += MAXN + 1 - t2.a[i]; | |
} else t1.a[i] -= t2.a[i]; | |
} | |
t1.len = big; | |
while(t1.a[len - 1] == 0 && t1.len > 1) { | |
t1.len--; | |
big--; | |
} | |
if(flag)t1.a[big-1]=0-t1.a[big-1]; | |
return t1; | |
} | |
BigNum BigNum::operator*(const BigNum & T) const { | |
BigNum ret; | |
int i,j,up; | |
int temp,temp1; | |
for(i = 0 ; i < len ; i++) { | |
up = 0; | |
for(j = 0 ; j < T.len ; j++) { | |
temp = a[i] * T.a[j] + ret.a[i + j] + up; | |
if(temp > MAXN) { | |
temp1 = temp - temp / (MAXN + 1) * (MAXN + 1); | |
up = temp / (MAXN + 1); | |
ret.a[i + j] = temp1; | |
} else { | |
up = 0; | |
ret.a[i + j] = temp; | |
} | |
} | |
if(up != 0) | |
ret.a[i + j] = up; | |
} | |
ret.len = i + j; | |
while(ret.a[ret.len - 1] == 0 && ret.len > 1) ret.len--; | |
return ret; | |
} | |
BigNum BigNum::operator/(const int & b) const { | |
BigNum ret; | |
int i,down = 0; | |
for(i = len - 1 ; i >= 0 ; i--) { | |
ret.a[i] = (a[i] + down * (MAXN + 1)) / b; | |
down = a[i] + down * (MAXN + 1) - ret.a[i] * b; | |
} | |
ret.len = len; | |
while(ret.a[ret.len - 1] == 0 && ret.len > 1) ret.len--; | |
return ret; | |
} | |
int BigNum::operator %(const int & b) const { | |
int i,d=0; | |
for (i = len-1; i>=0; i--) { | |
d = ((d * (MAXN+1))% b + a[i])% b; | |
} | |
return d; | |
} | |
BigNum BigNum::operator^(const int & n) const { | |
BigNum t,ret(1); | |
if(n<0)exit(-1); | |
if(n==0)return 1; | |
if(n==1)return *this; | |
int m=n; | |
while(m>1) { | |
t=*this; | |
int i; | |
for(i=1;i<<1<=m;i<<=1) { | |
t=t*t; | |
} | |
m-=i; | |
ret=ret*t; | |
if(m==1)ret=ret*(*this); | |
} | |
return ret; | |
} | |
bool BigNum::operator>(const BigNum & T) const { | |
int ln; | |
if(len > T.len) return true; | |
else if(len == T.len) { | |
ln = len - 1; | |
while(a[ln] == T.a[ln] && ln >= 0) ln--; | |
if(ln >= 0 && a[ln] > T.a[ln]) return true; | |
else return false; | |
} else return false; | |
} | |
void BigNum::print() { | |
int i; | |
cout << a[len - 1]; | |
for(i = len - 2 ; i >= 0 ; i--) { | |
cout.width(DLEN); | |
cout.fill('0'); | |
cout << a[i]; | |
} | |
} | |
//读取整数 | |
const int ok = 1; | |
int get_val(int & ret) { | |
ret = 0; | |
char ch; | |
while ((ch=getchar()) > '9' || ch < '0') ; | |
do { | |
ret = ret*10 + ch - '0'; | |
} while ((ch=getchar()) <= '9' && ch >= '0') ; | |
return ok; | |
} | |
//带负数 | |
int get_val(int & ret) { | |
ret = 0; | |
char ch; | |
bool neg = false; | |
while (((ch=getchar()) > '9' || ch < '0') && ch!='-') ; | |
if (ch == '-') { | |
neg = true; | |
while ((ch=getchar()) > '9' || ch < '0') ; | |
} | |
do { | |
ret = ret*10 + ch - '0'; | |
} while ((ch=getchar()) <= '9' && ch >= '0') ; | |
ret = (neg? -ret : ret); | |
return ok; | |
} | |
//读取整数,可判EOF和EOL | |
const int eof = -1; | |
const int eol = -2; | |
int get_val(int & ret) { | |
ret = 0; | |
char ch; | |
while (((ch=getchar()) > '9' || ch < '0') && ch!=EOF) ; | |
if (ch == EOF) return eof; | |
do { | |
ret = ret*10 + ch - '0'; | |
} while ((ch=getchar()) <= '9' && ch >= '0') ; | |
if (ch == '\n') return eol; | |
return ok; | |
} | |
//读取浮点数 | |
int get_val(double & ret) { | |
ret = 0; | |
double base = 0.1; | |
char ch; | |
bool dot = false, neg = false; | |
while (((ch=getchar()) > '9' || ch < '0') && ch != '.' && ch != '-') ; | |
if (ch == '-') { | |
neg = true; | |
while (((ch=getchar()) > '9' || ch < '0') && ch != '.' && ch != '-') ; | |
} | |
do { | |
if (ch == '.') { | |
dot = true; | |
continue; | |
} | |
if (dot) { | |
ret += (ch-'0') * base; | |
base *= 0.1; | |
} else ret = ret*10 + (ch-'0'); | |
} while (((ch=getchar()) <= '9' && ch >= '0') || ch == '.') ; | |
ret = (neg? -ret : ret); | |
return ok; | |
} | |
typedef long long LL; | |
//LL MultiMod(LL a, LL b, LL c) { | |
// if (b) | |
// return (a * (b & 1) % c + (MultiMod(a, b >> 1, c) << 1)) % c; | |
// return 0; | |
//} | |
LL MultiMod(LL a, LL b, LL c) { | |
LL ret = 0, d = a; | |
for (; b; b >>= 1, d <<= 1, d %= c) | |
if ((b & 1)) | |
ret = (ret + d) % c; | |
return ret; | |
} | |
// 128-bits integer's power with mod in O(64*LogN) | |
LL ModPower(LL base, LL exp, LL mod) { | |
LL ret = 1; | |
for (; exp; exp >>= 1, base = MultiMod(base, base, mod)) | |
if ((exp & 1)) | |
ret = MultiMod(ret, base, mod); | |
return ret; | |
} |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment