X
struct Bignum{
#define VV 10010
#define CONT int
#define WID 10000
private:
CONT bit[VV];
int bitlen;
bool flag;
public:
int getlen(){
return bitlen;
}
CONT getpw(int x){
switch (x)
{
case 0:return (CONT)1;
case 1:return (CONT)10;
case 2:return (CONT)100;
case 3:return (CONT)1000;
case 4:return (CONT)10000;
case 5:return (CONT)100000;
case 6:return (CONT)1000000;
case 7:return (CONT)10000000;
case 8:return (CONT)100000000;
case 9:return (CONT)1000000000;
default :return (CONT)-1;
}
}
Bignum(){ bitlen=1; bit[0]=0; flag=false;}
~Bignum(){}
Bignum(CONT x){
if(x<0) flag=true,x=-x;
else flag=false;
bitlen=0;
if(!x) bit[bitlen++]=0;
while(x){
bit[bitlen++]=x%WID;
x/=WID;
}
}
Bignum(char str[]){
const int wid=(int)sizeof(CONT);
int end;
if(str[0]=='-'){ end=1; flag=true; }else { end=0; flag=false; }
int i;
CONT mid=0,p=0;
for(i=0;str[i];i++);--i;
for(bitlen=0;i>=end;i--){
mid+=getpw(p)*(str[i]-'0'); p++;
if(p>=wid){ bit[bitlen++]=mid; p=0; mid=0; }
}
if(mid)bit[bitlen++]=mid;
for(i=bitlen-1;i>0&&!bit[i];i--); bitlen=i+1;
if(flag&&bitlen==1&&bit[0]==0)flag=false;
}
void sprint(CONT x){
if(x<0) flag=true,x=-x;
else flag=false;
bitlen=0;
if(!x) bit[bitlen++]=0;
while(x){
bit[bitlen++]=x%WID;
x/=WID;
}
}
void sprint(char str[]){
const int wid=(int)sizeof(CONT);
int end;
if(str[0]=='-'){ end=1; flag=true; }else { end=0; flag=false; }
int i;
CONT mid=0,p=0;
for(i=0;str[i];i++);--i;
for(bitlen=0;i>=end;i--){
mid+=getpw(p)*(str[i]-'0'); p++;
if(p>=wid){ bit[bitlen++]=mid; p=0; mid=0; }
}
if(mid)bit[bitlen++]=mid;
for(i=bitlen-1;i>0&&!bit[i];i--); bitlen=i+1;
if(flag&&bitlen==1&&bit[0]==0)flag=false;
}
bool scan(){
char str[VV*((int)sizeof(CONT))+1];
int ret=scanf("%s",str);
sprint(str);
return ret!=-1;
}
void print(){
const int wid=(int)sizeof(CONT);
if(flag) putchar('-');
if(wid==(int)sizeof(int)){
printf("%d",bit[bitlen-1]);
for(int i=bitlen-2;i>=0;i--) printf("%04d",bit[i]);
}
else{
printf("%I64d",bit[bitlen-1]);
for(int i=bitlen-2;i>=0;i--) printf("%08I64d",bit[i]);
}
}
friend istream& operator>>(istream &in,Bignum &b){
char str[VV*((int)sizeof(CONT))+1];
in>>str;
b.sprint(str);
return in;
}
friend ostream& operator<<(ostream &out,Bignum b){
out<<b.bit[b.bitlen-1];
for(int i=b.bitlen-2;i>=0;i--){
out.width((int)sizeof(CONT));
out.fill('0');
out<<b.bit[i];
}
return out;
}
void zero(){ for(int i=0;i<VV;i++)bit[i]=0; bitlen=1; bit[0]=0; flag=false; }
bool ZERO(){ return (bitlen==1&&bit[0]==0); }
bool odd(){ return bit[0]&1; }
void negation(){
flag=!flag;
if(flag&&bitlen==1&&bit[0]==0)flag=false;
}
void abs(){ if(flag)flag=false; }
void details(char *str = "num"){
printf("[%s->bitlen = %d]\n[%s->flag = %d]\n",str,bitlen,str,flag);
}
friend bool operator==(Bignum &a,Bignum &b){
if(a.flag!=b.flag||a.bitlen!=b.bitlen) return false;
for(int i=a.bitlen-1;i>=0;i--) if(a.bit[i]!=b.bit[i]) return false;
return true;
}
friend bool operator!=(Bignum &a,Bignum &b){ return !(a==b); }
friend bool operator==(Bignum &a,CONT &b){ Bignum c(b); return a==c; }
friend bool operator==(CONT &a,Bignum &b){ return b==a; }
friend bool operator!=(Bignum &a,CONT &b){ Bignum c(b); return a!=c; }
friend bool operator!=(CONT &a,Bignum &b){ return b!=a; }
friend bool operator>(Bignum &a,Bignum &b){
if(a.flag==b.flag){
if(a.bitlen==b.bitlen){
if(a.flag){
for(int i=a.bitlen-1;i>=0;i--)
if(a.bit[i]!=b.bit[i]) return a.bit[i]<b.bit[i];
}
else{
for(int i=a.bitlen-1;i>=0;i--)
if(a.bit[i]!=b.bit[i]) return a.bit[i]>b.bit[i];
}
return false;
}
if(a.flag) return a.bitlen<b.bitlen;
return a.bitlen>b.bitlen;
}
return b.flag;
}
friend bool operator>(Bignum &a,CONT &b){ Bignum c(b); return a>c; }
friend bool operator>(CONT &a,Bignum &b){ Bignum c(a); return c>b; }
friend bool operator<(Bignum &a,Bignum &b){ return b>a; }
friend bool operator<(Bignum &a,CONT &b){ Bignum c(b); return a<c; }
friend bool operator<(CONT &a,Bignum &b){ Bignum c(a); return c<b; }
friend bool operator>=(Bignum &a,Bignum &b){ return (a>b||a==b); }
friend bool operator>=(Bignum &a,CONT &b){ Bignum c(b); return a>=c; }
friend bool operator>=(CONT &a,Bignum &b){ Bignum c(a); return c>=b; }
friend bool operator<=(Bignum &a,Bignum &b){ return (a<b||a==b); }
friend bool operator<=(Bignum &a,CONT &b){ Bignum c(b); return a<=c; }
friend bool operator<=(CONT &a,Bignum &b){ Bignum c(a); return c<=b; }
friend Bignum operator-(Bignum &a){
Bignum c=a; c.flag=!c.flag;
if(c.flag&&c.bitlen==1&&c.bit[0]==0)c.flag=false;
return c;
}
friend Bignum operator+(Bignum a,Bignum b){
Bignum ans((CONT)0);
if(a.ZERO()) return b; if(b.ZERO()) return a;
if(a.flag==b.flag){
ans.flag=a.flag;
int len=a.bitlen; if(b.bitlen>len) len=b.bitlen;
ans.bitlen=len;
int c=0;
for(int i=0;i<len;i++){
if(i>=a.bitlen){
ans.bit[i]=b.bit[i]+c; c=ans.bit[i]/WID; if(ans.bit[i]>=WID) ans.bit[i]%=WID;
continue;
}
else if(i>=b.bitlen){
ans.bit[i]=a.bit[i]+c; c=ans.bit[i]/WID; if(ans.bit[i]>=WID) ans.bit[i]%=WID;
continue;
}
else {
ans.bit[i]=a.bit[i]+b.bit[i]+c; c=ans.bit[i]/WID; if(ans.bit[i]>=WID) ans.bit[i]%=WID;
}
}
if(c) ans.bit[len++]=c;
ans.bitlen=len;
return ans;
}
else{
if(a.flag){
a.abs();
if(a>b) ans.flag=true;
else { ans=a; a=b; b=ans; ans.flag=false; }
}
else{
b.abs();
if(a>b) ans.flag=false;
else { ans=a; a=b; b=ans; ans.flag=true; }
}
int len=a.bitlen;
for(int i=0;i<len;i++){
if(i>=b.bitlen){
ans.bit[i]=a.bit[i];
continue;
}
if(a.bit[i]<b.bit[i]){
a.bit[i]+=WID;
a.bit[i+1]-=1;
}
ans.bit[i]=a.bit[i]-b.bit[i];
}
for(len=len-1;len>0&&ans.bit[len]==0;len--);
ans.bitlen=len+1;
return ans;
}
}
friend Bignum operator-(Bignum &a,Bignum b){
b.negation();
return a+b;
}
friend Bignum operator/(Bignum &a,CONT b){
Bignum ans;
if((a.flag&&b<0)||(!a.flag&&b>=0))ans.flag=false;
else ans.flag=true;
if(b<0)b=-b;
CONT c=0;
for(int i=a.bitlen-1;i>=0;i--){
c=c*WID+a.bit[i];
ans.bit[i]=c/b;
if(c>=b)
c%=b;
}
int len;
for(len=a.bitlen-1;len>0&&ans.bit[len]==0;len--);
ans.bitlen=len+1;
return ans;
}
friend Bignum operator*(Bignum &a,Bignum &b){
Bignum ans;
if(a.ZERO()||b.ZERO()) return ans;
if(a.flag==b.flag) ans.flag=false;
else ans.flag=true;
ans.bitlen=a.bitlen+b.bitlen;
for(int i=0;i<ans.bitlen;i++)ans.bit[i]=0;
for(int i=0;i<a.bitlen;i++){
for(int j=0;j<b.bitlen;j++){
int k=i+j;
ans.bit[k]+=a.bit[i]*b.bit[j];
ans.bit[k+1]+=ans.bit[k]/WID;
if(ans.bit[k]>=WID) ans.bit[k]%=WID;
}
}
while(ans.bit[ans.bitlen-1]==0&&ans.bitlen>1) ans.bitlen--;
return ans;
}
friend CONT operator%(Bignum &a,CONT b){
int ret=1;
if(a.flag) ret=-1;
if(b<0) b=-b;
CONT c=0;
for(int i=a.bitlen-1;i>=0;i--){
c=c*WID+a.bit[i];
if(c>=b) c%=b;
}
return ret*c;
}
friend Bignum operator*(Bignum a,CONT b){
if((a.flag&&b<0)||(!a.flag&&b>=0)) a.flag=false;
else a.flag=true;
if(b<0)b=-b;
int c=0;
int len=a.bitlen;
for(int i=0;i<len;i++){
a.bit[i]=a.bit[i]*b+c;
c=a.bit[i]/WID;
if(a.bit[i]>=WID) a.bit[i]%=WID;
}
while(c){
a.bit[len++]=c%WID;
c/=WID;
}
a.bitlen=len;
return a;
}
friend Bignum operator*(CONT a,Bignum b){ return b*a; }
friend Bignum operator+(Bignum a,CONT b){ Bignum ans(b); return a+ans; }
friend Bignum operator+(CONT a,Bignum b){ return b+a; }
friend Bignum operator^(Bignum a,CONT p){
Bignum ret(1);
for(;p;p>>=1){
if(p&1)ret=ret*a;
a=a*a;
}
return ret;
}
};
这里大数是大整型,可以大数比较大小,输入输出流,大数乘法,大数加减法,大数的普通整型次幂,大数与普通整型取余与除法。
可以有负数。
HDU1002,HDU1042以及 http://192.168.100.16/diy/contest_show.php?cid=11954 这个DIY的1005能AC。
另外HDU1402大数乘法这个题目将VV设置到100010然后用G++也能过。只不过稍微慢了点,因为没有用FFT,FFT正在学习中,等学会了更新有FFT的版本。
1402:
int main()
{
Bignum a,b,c;
while(a.scan(),b.scan())
{
c=a*b;
c.print();puts("");
}
}
输入输出流:
int main()
{
Bignum a,b,c;
while(cin>>a>>b)
{
c=a*b;
cout<<c<<endl;
}
}前者953MS,后者984MS。。。。。。运气不好就超时了。。。。
本文详细介绍了一种大数运算的实现方式,包括大数的加减乘除、比较及输入输出等功能,并提供了具体的应用实例,如解决HDU1002等编程题。
5656

被折叠的 条评论
为什么被折叠?



