5
已解决
董安雅
新手光能
新手光能
代码如下:
#include<bits/stdc++.h>
using namespace std;
namespace BIG_NUM{
namespace BN{
int a[50005],b[50005],c[100005];
string Mul(string x,string y){//乘法
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=a[0]+b[0];//积的位数
for(int i=1;i<=a[0];i++){
for(int j=1;j<=b[0];j++){
c[i+j-1]+=a[i]*b[j];//这里一定要+=
}
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
c[i]=c[i]+jw;
jw=c[i]/10;
c[i]%=10;
}
while(c[c[0]]==0)c[0]--;//高位连续0的情况
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
return z;
}
string Minus(string x,string y){//减法
if(x==y)return "0";
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=max(a[0],b[0]);//c[0]存差的位数
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
if(a[i]<b[i]){//借位的情况
a[i+1]--;
a[i]+=10;
}
c[i]=a[i]-b[i];
}
while(c[c[0]]==0)c[0]--;//高位连续0的情况
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
return z;
}
string Plus(string x,string y){//加法
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=max(a[0],b[0]);//c[0]存和的位数
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
c[i]=a[i]+b[i]+jw;
jw=c[i]/10;//先处理进位
c[i]%=10;
}
if(jw!=0)c[++c[0]]=jw;//判断是否进位,进位,位数+1,这一位为1
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
return z;
}
bool check_size(string x,string y){
if(x.size()>y.size())return false;
else if(x.size()<y.size())return true;
else{
if(x>y)return false;
else{
return true;
}
}
}
class abnormal:public exception{
private:
string message;
public:
abnormal(string other){
message=other;
}
const char* what(){
return message.c_str();
}
};
string Div(string x,string y){
if(y=="0"){
abnormal e("Divider cannot be 0.");
throw e;
return "NULL";
}
else if(!check_size(y,x))return "0";
string ans="";
while(1){
string a=x.substr(0,y.size());
if(!check_size(y,a))a+=x[y.size()];
int l=0,r=9;
string k,k2;
while(l<r){
int mid=(l+r+1)/2;
k=Mul(y,to_string(mid));
if(check_size(k,a))l=mid;
else r=mid-1;
}
string t=to_string(l);
ans+=t;
k=x.substr(a.size(),x.size()-a.size()+1);
k2=Mul(y,t);
x=Minus(a,k2);
if(x=="0")x="";
int len=x.size();
x+=k;
if(k=="")break;
else if(!check_size(y,x)&&k.size()==1){
ans+="0";
break;
}
while(len<y.size()-1){
ans+="0";
len++;
}
while(!check_size(y,x.substr(0,len+1))){
ans+="0";
len++;
}
}
return ans;
}
string Comple(string x,string y){
string t=Div(x,y);
string k=Minus(x,t);
return k;
}
}
class Big_num{
friend string to_string(Big_num x);
friend istream& operator>>(istream& is,const Big_num& num);
private:
#define Plus(x,y) BN::Plus(x,y)
#define Minus(x,y) BN::Minus(x,y)
#define Mul(x,y) BN::Mul(x,y)
#define Div(x,y) BN::Div(x,y)
#define Comple(x,y) BN::Comple(x,y)
string num;
public:
Big_num(){
num="0";
}
Big_num(string other){
num=other;
}
Big_num(const char* other){
num=other;
}
Big_num(int other){
num=to_string(other);
}
Big_num(short other){
num=to_string((int)other);
}
Big_num(long other){
num=to_string(other);
}
Big_num(long long other){
num=to_string(other);
}
Big_num(const Big_num& other){
num=other.num;
}
Big_num& operator=(Big_num other){
num=other.num;
return *this;
}
Big_num operator+(Big_num other){
string x=Plus(num,other.num);
Big_num y=x;
return y;
}
Big_num operator-(Big_num other){
string x=Minus(num,other.num);
Big_num y=x;
return y;
}
Big_num operator*(Big_num other){
string x=Mul(num,other.num);
Big_num y=x;
return y;
}
Big_num operator/(Big_num other){
string x=Div(num,other.num);
Big_num y=x;
return y;
}
Big_num operator%(Big_num other){
string x=Comple(num,other.num);
Big_num y=x;
return y;
}
};
string to_string(Big_num x){
return x.num;
}
ostream& operator<<(ostream& os,const Big_num& num){
os<<to_string(num);
return os;
}
istream& operator>>(istream& is,const Big_num& num){
is>>num.num;
return is;
}
}
using namespace BIG_NUM;
举个例子:
Big_num a="6534289857563748923958462",b="3782594234875294";
cout<<a+b<<endl;
然后就能得到结果了。
董安雅在2023-04-09 10:35:17追加了内容
#include<bits/stdc++.h>
using namespace std;
namespace BIG_NUM{
namespace BN{
int a[50005],b[50005],c[100005];
string Mul(string x,string y){//乘法
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=a[0]+b[0];//积的位数
for(int i=1;i<=a[0];i++){
for(int j=1;j<=b[0];j++){
c[i+j-1]+=a[i]*b[j];//这里一定要+=
}
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
c[i]=c[i]+jw;
jw=c[i]/10;
c[i]%=10;
}
while(c[c[0]]==0)c[0]--;//高位连续0的情况
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
return z;
}
string Minus(string x,string y){//减法
if(x==y)return "0";
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=max(a[0],b[0]);//c[0]存差的位数
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
if(a[i]<b[i]){//借位的情况
a[i+1]--;
a[i]+=10;
}
c[i]=a[i]-b[i];
}
while(c[c[0]]==0)c[0]--;//高位连续0的情况
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
return z;
}
string Plus(string x,string y){//加法
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=max(a[0],b[0]);//c[0]存和的位数
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
c[i]=a[i]+b[i]+jw;
jw=c[i]/10;//先处理进位
c[i]%=10;
}
if(jw!=0)c[++c[0]]=jw;//判断是否进位,进位,位数+1,这一位为1
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
return z;
}
bool check_size(string x,string y){
if(x.size()>y.size())return false;
else if(x.size()<y.size())return true;
else{
if(x>y)return false;
else{
return true;
}
}
}
class abnormal:public exception{
private:
string message;
public:
abnormal(string other){
message=other;
}
const char* what(){
return message.c_str();
}
};
string Div(string x,string y){
if(y=="0"){
abnormal e("Divider cannot be 0.");
throw e;
return "NULL";
}
else if(!check_size(y,x))return "0";
string ans="";
while(1){
string a=x.substr(0,y.size());
if(!check_size(y,a))a+=x[y.size()];
int l=0,r=9;
string k,k2;
while(l<r){
int mid=(l+r+1)/2;
k=Mul(y,to_string(mid));
if(check_size(k,a))l=mid;
else r=mid-1;
}
string t=to_string(l);
ans+=t;
k=x.substr(a.size(),x.size()-a.size()+1);
k2=Mul(y,t);
x=Minus(a,k2);
if(x=="0")x="";
int len=x.size();
x+=k;
if(k=="")break;
else if(!check_size(y,x)&&k.size()==1){
ans+="0";
break;
}
while(len<y.size()-1){
ans+="0";
len++;
}
while(!check_size(y,x.substr(0,len+1))){
ans+="0";
len++;
}
}
return ans;
}
string Comple(string x,string y){
string t=Div(x,y);
string k=Minus(x,Mul(t,y));
return k;
}
}
class Big_num{
friend string to_string(Big_num x);
friend istream& operator>>(istream& is,const Big_num& num);
private:
#define Plus(x,y) BN::Plus(x,y)
#define Minus(x,y) BN::Minus(x,y)
#define Mul(x,y) BN::Mul(x,y)
#define Div(x,y) BN::Div(x,y)
#define Comple(x,y) BN::Comple(x,y)
string num;
public:
Big_num(){
num="0";
}
Big_num(string other){
num=other;
}
Big_num(const char* other){
num=other;
}
Big_num(int other){
num=to_string(other);
}
Big_num(short other){
num=to_string((int)other);
}
Big_num(long other){
num=to_string(other);
}
Big_num(long long other){
num=to_string(other);
}
Big_num(const Big_num& other){
num=other.num;
}
Big_num& operator=(Big_num other){
num=other.num;
return *this;
}
Big_num operator+(Big_num other){
string x=Plus(num,other.num);
Big_num y=x;
return y;
}
Big_num operator-(Big_num other){
string x=Minus(num,other.num);
Big_num y=x;
return y;
}
Big_num operator*(Big_num other){
string x=Mul(num,other.num);
Big_num y=x;
return y;
}
Big_num operator/(Big_num other){
string x=Div(num,other.num);
Big_num y=x;
return y;
}
Big_num operator%(Big_num other){
string x=Comple(num,other.num);
Big_num y=x;
return y;
}
};
string to_string(Big_num x){
return x.num;
}
ostream& operator<<(ostream& os,const Big_num& num){
os<<to_string(num);
return os;
}
istream& operator>>(istream& is,Big_num& num){
is>>num.num;
return is;
}
}
using namespace BIG_NUM;
修复了某些BUG.
编译器为。
董安雅在2023-04-09 13:24:26追加了内容
最新代码:
#include<bits/stdc++.h>
using namespace std;
namespace BIG_NUM{
namespace BN{
int a[50005],b[50005],c[100005];
string Mul(string x,string y){//乘法
bool flag=false;
if(x[0]=='-'){
flag=!flag;
x.erase(0,1);
}
if(y[0]=='-'){
flag=!flag;
y.erase(0,1);
}
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=a[0]+b[0];//积的位数
for(int i=1;i<=a[0];i++){
for(int j=1;j<=b[0];j++){
c[i+j-1]+=a[i]*b[j];//这里一定要+=
}
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
c[i]=c[i]+jw;
jw=c[i]/10;
c[i]%=10;
}
while(c[c[0]]==0)c[0]--;//高位连续0的情况
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
z=(flag==true?"-":"")+z;
return z;
}
string Plus(string x,string y);//加法
string Minus(string x,string y){//减法
if(x==y)return "0";
if(x[0]=='-'&&y[0]=='-'){
return Minus(y.substr(1,y.size()-1),
x.substr(1,y.size()-1));
}
else if(x[0]=='-'&&y[0]!='-'){
string t=Plus(x.substr(1,x.size()-1),y);
t="-"+t;
return t;
}
else if(x[0]!='-'&&y[0]=='-'){
return Plus(x,y.substr(1,y.size()-1));
}
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=max(a[0],b[0]);//c[0]存差的位数
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
if(a[i]<b[i]){//借位的情况
a[i+1]--;
a[i]+=10;
}
c[i]=a[i]-b[i];
}
while(c[c[0]]==0)c[0]--;//高位连续0的情况
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
return z;
}
string Plus(string x,string y){//加法
if(x[0]=='-'&&y[0]=='-'){
string t=Plus(x.substr(1,x.size()-1),
y.substr(1,y.size()-1));
t="-"+t;
return t;
}
else if(x[0]=='-'&&y[0]!='-'){
return Minus(y,x.substr(1,x.size()-1));
}
else if(x[0]!='-'&&y[0]=='-'){
return Minus(x,y.substr(1,y.size()-1));
}
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=max(a[0],b[0]);//c[0]存和的位数
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
c[i]=a[i]+b[i]+jw;
jw=c[i]/10;//先处理进位
c[i]%=10;
}
if(jw!=0)c[++c[0]]=jw;//判断是否进位,进位,位数+1,这一位为1
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
return z;
}
bool check_size(string x,string y){
if(x.size()>y.size())return false;
else if(x.size()<y.size())return true;
else{
if(x>y)return false;
else{
return true;
}
}
}
class abnormal:public exception{
private:
string message;
public:
abnormal(string other){
message=other;
}
const char* what(){
return message.c_str();
}
};
string Div(string x,string y){
if(y=="0"){
abnormal e("Divider cannot be 0.");
throw e;
return "NULL";
}
else if(!check_size(y,x))return "0";
string ans="";
while(1){
string a=x.substr(0,y.size());
if(!check_size(y,a))a+=x[y.size()];
int l=0,r=9;
string k,k2;
while(l<r){
int mid=(l+r+1)/2;
k=Mul(y,to_string(mid));
if(check_size(k,a))l=mid;
else r=mid-1;
}
string t=to_string(l);
ans+=t;
k=x.substr(a.size(),x.size()-a.size()+1);
k2=Mul(y,t);
x=Minus(a,k2);
if(x=="0")x="";
int len=x.size();
x+=k;
if(k=="")break;
else if(!check_size(y,x)&&k.size()==1){
ans+="0";
break;
}
while(len<y.size()-1){
ans+="0";
len++;
}
while(!check_size(y,x.substr(0,len+1))){
ans+="0";
len++;
}
}
return ans;
}
string Comple(string x,string y){
string t=Div(x,y);
string k=Minus(x,Mul(t,y));
return k;
}
}
class Big_num{
friend string to_string(Big_num x);
friend istream& operator>>(istream& is,Big_num& num);
private:
#define Plus(x,y) BN::Plus(x,y)
#define Minus(x,y) BN::Minus(x,y)
#define Mul(x,y) BN::Mul(x,y)
#define Div(x,y) BN::Div(x,y)
#define Comple(x,y) BN::Comple(x,y)
string num;
public:
Big_num(){
num="0";
}
Big_num(string other){
num=other;
}
Big_num(const char* other){
num=other;
}
Big_num(int other){
num=to_string(other);
}
Big_num(short other){
num=to_string((int)other);
}
Big_num(long other){
num=to_string(other);
}
Big_num(long long other){
num=to_string(other);
}
Big_num(const Big_num& other){
num=other.num;
}
Big_num& operator=(Big_num other){
num=other.num;
return *this;
}
Big_num operator+(Big_num other){
string x=Plus(num,other.num);
Big_num y=x;
return y;
}
Big_num operator-(Big_num other){
string x=Minus(num,other.num);
Big_num y=x;
return y;
}
Big_num operator*(Big_num other){
string x=Mul(num,other.num);
Big_num y=x;
return y;
}
Big_num operator/(Big_num other){
string x=Div(num,other.num);
Big_num y=x;
return y;
}
Big_num operator%(Big_num other){
string x=Comple(num,other.num);
Big_num y=x;
return y;
}
};
string to_string(Big_num x){
return x.num;
}
ostream& operator<<(ostream& os,const Big_num& num){
os<<to_string(num);
return os;
}
istream& operator>>(istream& is,Big_num& num){
is>>num.num;
return is;
}
}
using namespace BIG_NUM;
修复了一个BUG.
支持大负整数的加减乘法运算了!
编译器不变。
董安雅在2023-04-09 13:25:06追加了内容
改个标题。
下次继续更新!
董安雅在2023-04-14 18:57:16追加了内容
#include<bits/stdc++.h>
using namespace std;
namespace BIG_NUM{
namespace BN{
int a[50005],b[50005],c[100005];
string Mul(string x,string y){//乘法
bool flag=false;
if(x[0]=='-'){
flag=!flag;
x.erase(0,1);
}
if(y[0]=='-'){
flag=!flag;
y.erase(0,1);
}
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=a[0]+b[0];//积的位数
for(int i=1;i<=a[0];i++){
for(int j=1;j<=b[0];j++){
c[i+j-1]+=a[i]*b[j];//这里一定要+=
}
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
c[i]=c[i]+jw;
jw=c[i]/10;
c[i]%=10;
}
while(c[c[0]]==0)c[0]--;//高位连续0的情况
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
z=(flag==true?"-":"")+z;
return z;
}
string Plus(string x,string y);//加法
string Minus(string x,string y){//减法
if(x==y)return "0";
if(x[0]=='-'&&y[0]=='-'){
return Minus(y.substr(1,y.size()-1),
x.substr(1,y.size()-1));
}
else if(x[0]=='-'&&y[0]!='-'){
string t=Plus(x.substr(1,x.size()-1),y);
t="-"+t;
return t;
}
else if(x[0]!='-'&&y[0]=='-'){
return Plus(x,y.substr(1,y.size()-1));
}
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=max(a[0],b[0]);//c[0]存差的位数
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
if(a[i]<b[i]){//借位的情况
a[i+1]--;
a[i]+=10;
}
c[i]=a[i]-b[i];
}
while(c[c[0]]==0)c[0]--;//高位连续0的情况
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
return z;
}
string Plus(string x,string y){//加法
if(x[0]=='-'&&y[0]=='-'){
string t=Plus(x.substr(1,x.size()-1),
y.substr(1,y.size()-1));
t="-"+t;
return t;
}
else if(x[0]=='-'&&y[0]!='-'){
return Minus(y,x.substr(1,x.size()-1));
}
else if(x[0]!='-'&&y[0]=='-'){
return Minus(x,y.substr(1,y.size()-1));
}
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=max(a[0],b[0]);//c[0]存和的位数
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
c[i]=a[i]+b[i]+jw;
jw=c[i]/10;//先处理进位
c[i]%=10;
}
if(jw!=0)c[++c[0]]=jw;//判断是否进位,进位,位数+1,这一位为1
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
return z;
}
bool check_size(string x,string y){
if(x.size()>y.size())return false;
else if(x.size()<y.size())return true;
else{
if(x>y)return false;
else{
return true;
}
}
}
class abnormal:public exception{
private:
string message;
public:
abnormal(string other){
message=other;
}
const char* what(){
return message.c_str();
}
};
string Div(string x,string y){
bool flag=false;
if(x[0]=='-'){
flag=!flag;
x.erase(0,1);
}
if(y[0]=='-'){
flag=!flag;
y.erase(0,1);
}
if(y=="0"){
abnormal e("Divider cannot be 0.");
throw e;
return "NULL";
}
else if(!check_size(y,x))return "0";
string ans="";
while(1){
string a=x.substr(0,y.size());
if(!check_size(y,a))a+=x[y.size()];
int l=0,r=9;
string k,k2;
while(l<r){
int mid=(l+r+1)/2;
k=Mul(y,to_string(mid));
if(check_size(k,a))l=mid;
else r=mid-1;
}
string t=to_string(l);
ans+=t;
k=x.substr(a.size(),x.size()-a.size()+1);
k2=Mul(y,t);
x=Minus(a,k2);
if(x=="0")x="";
int len=x.size();
x+=k;
if(k=="")break;
else if(!check_size(y,x)&&k.size()==1){
ans+="0";
break;
}
while(len<y.size()-1){
ans+="0";
len++;
}
while(!check_size(y,x.substr(0,len+1))){
ans+="0";
len++;
}
}
ans=(flag==true?"-":"")+ans;
return ans;
}
string Comple(string x,string y){
string t=Div(x,y);
string k=Minus(x,Mul(t,y));
return k;
}
}
class Big_num{
friend string to_string(Big_num x);
friend istream& operator>>(istream& is,Big_num& num);
private:
#define Plus(x,y) BN::Plus(x,y)
#define Minus(x,y) BN::Minus(x,y)
#define Mul(x,y) BN::Mul(x,y)
#define Div(x,y) BN::Div(x,y)
#define Comple(x,y) BN::Comple(x,y)
string num;
public:
Big_num(){
num="0";
}
Big_num(string other){
num=other;
}
Big_num(const char* other){
num=other;
}
Big_num(int other){
num=to_string(other);
}
Big_num(short other){
num=to_string((int)other);
}
Big_num(long other){
num=to_string(other);
}
Big_num(long long other){
num=to_string(other);
}
Big_num(const Big_num& other){
num=other.num;
}
Big_num& operator=(Big_num other){
num=other.num;
return *this;
}
Big_num operator+(Big_num other){
string x=Plus(num,other.num);
Big_num y=x;
return y;
}
Big_num operator-(Big_num other){
string x=Minus(num,other.num);
Big_num y=x;
return y;
}
Big_num operator*(Big_num other){
string x=Mul(num,other.num);
Big_num y=x;
return y;
}
Big_num operator/(Big_num other){
string x=Div(num,other.num);
Big_num y=x;
return y;
}
Big_num operator%(Big_num other){
string x=Comple(num,other.num);
Big_num y=x;
return y;
}
};
string to_string(Big_num x){
return x.num;
}
ostream& operator<<(ostream& os,const Big_num& num){
os<<to_string(num);
return os;
}
istream& operator>>(istream& is,Big_num& num){
is>>num.num;
return is;
}
}
using namespace BIG_NUM;
编译器不变。
已支持负高精度整数的除法.
董安雅在2023-04-14 22:16:06追加了内容
#include<bits/stdc++.h>
using namespace std;
namespace BIG_NUM{
namespace BN{
int a[50005],b[50005],c[100005];
string Plus(string x,string y);//加法
string Minus(string x,string y){//减法
if(x==y)return "0";
if(x[0]=='-'&&y[0]=='-'){
return Minus(y.substr(1,y.size()-1),
x.substr(1,y.size()-1));
}
else if(x[0]=='-'&&y[0]!='-'){
string t=Plus(x.substr(1,x.size()-1),y);
t="-"+t;
return t;
}
else if(x[0]!='-'&&y[0]=='-'){
return Plus(x,y.substr(1,y.size()-1));
}
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=max(a[0],b[0]);//c[0]存差的位数
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
if(a[i]<b[i]){//借位的情况
a[i+1]--;
a[i]+=10;
}
c[i]=a[i]-b[i];
}
while(c[c[0]]==0)c[0]--;//高位连续0的情况
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
return z;
}
string Plus(string x,string y){//加法
if(x[0]=='-'&&y[0]=='-'){
string t=Plus(x.substr(1,x.size()-1),
y.substr(1,y.size()-1));
t="-"+t;
return t;
}
else if(x[0]=='-'&&y[0]!='-'){
return Minus(y,x.substr(1,x.size()-1));
}
else if(x[0]!='-'&&y[0]=='-'){
return Minus(x,y.substr(1,y.size()-1));
}
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=max(a[0],b[0]);//c[0]存和的位数
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
c[i]=a[i]+b[i]+jw;
jw=c[i]/10;//先处理进位
c[i]%=10;
}
if(jw!=0)c[++c[0]]=jw;//判断是否进位,进位,位数+1,这一位为1
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
return z;
}
string mobm(string x,char y){
vector<int> ans;
string t="";
int k=(int)y-48,len=x.size();
for(int i=len-1;i>=0;i--){
int num=((int)x[i]-48)*k;
if(ans.size()<len-i)ans.push_back(0);
ans[len-i-1]+=num%10;
ans.push_back(0);
ans[len-i]+=num/10;
}
while(ans.size()>1&&ans[ans.size()-1]==0){
ans.pop_back();
}
while(!ans.empty()){
t+=(char)(ans.back()+48);
ans.pop_back();
}
return t;
}
string azate(int len){
string ans="";
for(int i=1;i<=len;i++){
ans+="0";
}
return ans;
}
string Mul(string x,string y){
bool flag=false;
if(x[0]=='-'){
flag=!flag;
x.erase(0,1);
}
if(y[0]=='-'){
flag=!flag;
y.erase(0,1);
}
string f[10],k[50005];
for(int i=0;i<10;i++){
f[i]="+_-INF";
}
f[0]="0",f[1]=y;
int len=x.size();
for(int i=len-1;i>=0;i--){
if(f[(int)x[i]-48]!="+_-INF"){
k[i]=f[(int)x[i]-48];
continue;
}
k[i]=mobm(y,x[i]);
k[i]+=azate(len-i-1);
}
string ans=k[len-1];
for(int i=len-2;i>=0;i--){
ans=Plus(ans,k[i]);
}
ans=(flag==true?"-":"")+ans;
return ans;
}
bool check_size(string x,string y){
if(x.size()>y.size())return false;
else if(x.size()<y.size())return true;
else{
if(x>y)return false;
else{
return true;
}
}
}
class abnormal:public exception{
private:
string message;
public:
abnormal(string other){
message=other;
}
const char* what(){
return message.c_str();
}
};
string Div(string x,string y){
bool flag=false;
if(x[0]=='-'){
flag=!flag;
x.erase(0,1);
}
if(y[0]=='-'){
flag=!flag;
y.erase(0,1);
}
if(y=="0"){
abnormal e("Divider cannot be 0.");
throw e;
return "NULL";
}
else if(!check_size(y,x))return "0";
string ans="";
while(1){
string a=x.substr(0,y.size());
if(!check_size(y,a))a+=x[y.size()];
int l=0,r=9;
string k,k2;
while(l<r){
int mid=(l+r+1)/2;
k=Mul(y,to_string(mid));
if(check_size(k,a))l=mid;
else r=mid-1;
}
string t=to_string(l);
ans+=t;
k=x.substr(a.size(),x.size()-a.size()+1);
k2=Mul(y,t);
x=Minus(a,k2);
if(x=="0")x="";
int len=x.size();
x+=k;
if(k=="")break;
else if(!check_size(y,x)&&k.size()==1){
ans+="0";
break;
}
while(len<y.size()-1){
ans+="0";
len++;
}
while(!check_size(y,x.substr(0,len+1))){
ans+="0";
len++;
}
}
ans=(flag==true?"-":"")+ans;
return ans;
}
string Comple(string x,string y){
string t=Div(x,y);
string k=Minus(x,Mul(t,y));
return k;
}
}
class Big_num{
friend string to_string(Big_num x);
friend istream& operator>>(istream& is,Big_num& num);
private:
#define Plus(x,y) BN::Plus(x,y)
#define Minus(x,y) BN::Minus(x,y)
#define Mul(x,y) BN::Mul(x,y)
#define Div(x,y) BN::Div(x,y)
#define Comple(x,y) BN::Comple(x,y)
string num;
public:
Big_num(){
num="0";
}
Big_num(string other){
num=other;
}
Big_num(const char* other){
num=other;
}
Big_num(int other){
num=to_string(other);
}
Big_num(short other){
num=to_string((int)other);
}
Big_num(long other){
num=to_string(other);
}
Big_num(long long other){
num=to_string(other);
}
Big_num(const Big_num& other){
num=other.num;
}
Big_num& operator=(Big_num other){
num=other.num;
return *this;
}
Big_num operator+(Big_num other){
string x=Plus(num,other.num);
Big_num y=x;
return y;
}
Big_num operator-(Big_num other){
string x=Minus(num,other.num);
Big_num y=x;
return y;
}
Big_num operator*(Big_num other){
string x=Mul(num,other.num);
Big_num y=x;
return y;
}
Big_num operator/(Big_num other){
string x=Div(num,other.num);
Big_num y=x;
return y;
}
Big_num operator%(Big_num other){
string x=Comple(num,other.num);
Big_num y=x;
return y;
}
};
string to_string(Big_num x){
return x.num;
}
ostream& operator<<(ostream& os,const Big_num& num){
os<<to_string(num);
return os;
}
istream& operator>>(istream& is,Big_num& num){
is>>num.num;
return is;
}
}
using namespace BIG_NUM;
优化了乘法的时间复杂度(即将使用FFT优化)
董安雅在2023-04-16 12:49:03追加了内容
#include<bits/stdc++.h>
using namespace std;
namespace BIG_NUM{
namespace BN{
int a[50005],b[50005],c[100005];
string k[50005];
string f[10];
/*
const double PI = acos(-1.0);
struct Complex {
double x, y;
Complex(double _x = 0.0, double _y = 0.0) {
x = _x;
y = _y;
}
Complex operator-(const Complex &b) const {
return Complex(x - b.x, y - b.y);
}
Complex operator+(const Complex &b) const {
return Complex(x + b.x, y + b.y);
}
Complex operator*(const Complex &b) const {
return Complex(x * b.x - y * b.y, x * b.y + y * b.x);
}
};
void change(Complex y[], int len) {
int i, j, k;
for (int i = 1, j = len / 2; i < len - 1; i++) {
if (i < j) std::swap(y[i], y[j]);
k = len / 2;
while (j >= k) {
j = j - k;
k = k / 2;
}
if (j < k) j += k;
}
}
void fft(Complex y[], int len, int on) {
change(y, len);
for (int h = 2; h <= len; h <<= 1) {
Complex wn(cos(2 * PI / h), sin(on * 2 * PI / h));
for (int j = 0; j < len; j += h) {
Complex w(1, 0);
for (int k = j; k < j + h / 2; k++) {
Complex u = y[k];
Complex t = w * y[k + h / 2];
y[k] = u + t;
y[k + h / 2] = u - t;
w = w * wn;
}
}
}
if (on == -1) {
for (int i = 0; i < len; i++) {
y[i].x /= len;
}
}
}
string Mul(string x,string y){//乘法
bool flag=false;
if(x[0]=='-'){
flag=!flag;
x.erase(0,1);
}
if(y[0]=='-'){
flag=!flag;
y.erase(0,1);
}
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=a[0]+b[0];//积的位数
for(int i=1;i<=a[0];i++){
for(int j=1;j<=b[0];j++){
c[i+j-1]+=a[i]*b[j];//这里一定要+=
}
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
c[i]=c[i]+jw;
jw=c[i]/10;
c[i]%=10;
}
while(c[c[0]]==0)c[0]--;//高位连续0的情况
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
z=(flag==true?"-":"")+z;
return z;
}
*/
string Plus(string x,string y);//加法
string Minus(string x,string y){//减法
if(x==y)return "0";
if(x[0]=='-'&&y[0]=='-'){
return Minus(y.substr(1,y.size()-1),
x.substr(1,y.size()-1));
}
else if(x[0]=='-'&&y[0]!='-'){
string t=Plus(x.substr(1,x.size()-1),y);
t="-"+t;
return t;
}
else if(x[0]!='-'&&y[0]=='-'){
return Plus(x,y.substr(1,y.size()-1));
}
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=max(a[0],b[0]);//c[0]存差的位数
for(int i=a[0]+1;i<=c[0];i++){
a[i]=0;
}
for(int i=b[0]+1;i<=c[0];i++){
b[i]=0;
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
if(a[i]<b[i]){//借位的情况
a[i+1]--;
a[i]+=10;
}
c[i]=a[i]-b[i];
}
while(c[c[0]]==0)c[0]--;//高位连续0的情况
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
return z;
}
string Plus(string x,string y){//加法
if(x[0]=='-'&&y[0]=='-'){
string t=Plus(x.substr(1,x.size()-1),
y.substr(1,y.size()-1));
t="-"+t;
return t;
}
else if(x[0]=='-'&&y[0]!='-'){
return Minus(y,x.substr(1,x.size()-1));
}
else if(x[0]!='-'&&y[0]=='-'){
return Minus(x,y.substr(1,y.size()-1));
}
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=max(a[0],b[0]);//c[0]存和的位数
for(int i=a[0]+1;i<=c[0];i++){
a[i]=0;
}
for(int i=b[0]+1;i<=c[0];i++){
b[i]=0;
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
c[i]=a[i]+b[i]+jw;
jw=c[i]/10;//先处理进位
c[i]%=10;
}
if(jw!=0)c[++c[0]]=jw;//判断是否进位,进位,位数+1,这一位为1
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
return z;
}
void Plus(){//加法
c[0]=max(a[0],b[0]);//c[0]存和的位数
for(int i=a[0]+1;i<=c[0];i++){
a[i]=0;
}
for(int i=b[0]+1;i<=c[0];i++){
b[i]=0;
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
c[i]=a[i]+b[i]+jw;
jw=c[i]/10;//先处理进位
c[i]%=10;
}
if(jw!=0)c[++c[0]]=jw;//判断是否进位,进位,位数+1,这一位为1
}
void Minus(){//减法
c[0]=max(a[0],b[0]);//c[0]存差的位数
for(int i=a[0]+1;i<=c[0];i++){
a[i]=0;
}
for(int i=b[0]+1;i<=c[0];i++){
b[i]=0;
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
if(a[i]<b[i]){//借位的情况
a[i+1]--;
a[i]+=10;
}
c[i]=a[i]-b[i];
}
while(c[c[0]]==0)c[0]--;//高位连续0的情况
}
string mobm(string x,char y){
vector<int> ans;
string t="";
int k=(int)y-48,len=x.size();
for(int i=len-1;i>=0;i--){
int num=((int)x[i]-48)*k;
if(ans.size()<len-i)ans.push_back(0);
ans[len-i-1]+=num%10;
ans.push_back(0);
ans[len-i]+=num/10;
}
while(ans.size()>1&&ans[ans.size()-1]==0){
ans.pop_back();
}
while(!ans.empty()){
t+=(char)(ans.back()+48);
ans.pop_back();
}
return t;
}
string azate(int len){
string ans="";
for(int i=1;i<=len;i++){
ans+="0";
}
return ans;
}
string Mul(string x,string y){
bool flag=false;
if(x[0]=='-'){
flag=!flag;
x.erase(0,1);
}
if(y[0]=='-'){
flag=!flag;
y.erase(0,1);
}
for(int i=0;i<10;i++){
f[i]="+_-INF";
}
f[0]="0",f[1]=y;
int len=x.size();
for(int i=len-1;i>=0;i--){
if(f[(int)x[i]-48]!="+_-INF"){
k[i]=f[(int)x[i]-48];
continue;
}
k[i]=mobm(y,x[i]);
k[i]+=azate(len-i-1);
}
string ans="";
c[0]=k[len-1].size();
for(int i=1;i<=c[0];i++){
c[i]=k[len-1][c[0]-i]-'0';
}
for(int i=len-2;i>=0;i--){
a[0]=c[0];
for(int j=1;j<=c[0];j++){
a[j]=c[j];
}
b[0]=k[i].size();
for(int j=1;j<=b[0];j++){
b[j]=k[i][b[0]-j]-'0';
}
Plus();
}
for(int i=c[0];i>=1;i--)ans=ans+(char)(c[i]+48);
ans=(flag==true?"-":"")+ans;
return ans;
}
bool check_size(string x,string y){
if(x.size()>y.size())return false;
else if(x.size()<y.size())return true;
else{
if(x>y)return false;
else{
return true;
}
}
}
class abnormal:public exception{
private:
string message;
public:
abnormal(string other){
message=other;
}
const char* what(){
return message.c_str();
}
};
string Div(string x,string y){
bool flag=false;
if(x[0]=='-'){
flag=!flag;
x.erase(0,1);
}
if(y[0]=='-'){
flag=!flag;
y.erase(0,1);
}
if(y=="0"){
abnormal e("Divider cannot be 0.");
throw e;
return "NULL";
}
else if(!check_size(y,x))return "0";
string ans="";
while(1){
string a=x.substr(0,y.size());
if(!check_size(y,a))a+=x[y.size()];
int l=0,r=9;
string k,k2;
while(l<r){
int mid=(l+r+1)/2;
k=Mul(y,to_string(mid));
if(check_size(k,a))l=mid;
else r=mid-1;
}
string t=to_string(l);
ans+=t;
k=x.substr(a.size(),x.size()-a.size()+1);
k2=Mul(y,t);
x=Minus(a,k2);
if(x=="0")x="";
int len=x.size();
x+=k;
if(k=="")break;
else if(!check_size(y,x)&&k.size()==1){
ans+="0";
break;
}
while(len<y.size()-1){
ans+="0";
len++;
}
while(!check_size(y,x.substr(0,len+1))){
ans+="0";
len++;
}
}
ans=(flag==true?"-":"")+ans;
return ans;
}
string Comple(string x,string y){
string t=Div(x,y);
string k=Minus(x,Mul(t,y));
return k;
}
}
class Big_num{
friend string to_string(Big_num x);
friend istream& operator>>(istream& is,Big_num& num);
private:
#define Plus(x,y) BN::Plus(x,y)
#define Minus(x,y) BN::Minus(x,y)
#define Mul(x,y) BN::Mul(x,y)
#define Div(x,y) BN::Div(x,y)
#define Comple(x,y) BN::Comple(x,y)
string num;
public:
Big_num(){
num="0";
}
Big_num(string other){
num=other;
}
Big_num(const char* other){
num=other;
}
Big_num(int other){
num=to_string(other);
}
Big_num(short other){
num=to_string((int)other);
}
Big_num(long other){
num=to_string(other);
}
Big_num(long long other){
num=to_string(other);
}
Big_num(const Big_num& other){
num=other.num;
}
Big_num& operator=(Big_num other){
num=other.num;
return *this;
}
Big_num operator+(Big_num other){
string x=Plus(num,other.num);
Big_num y=x;
return y;
}
Big_num operator-(Big_num other){
string x=Minus(num,other.num);
Big_num y=x;
return y;
}
Big_num operator*(Big_num other){
string x=Mul(num,other.num);
Big_num y=x;
return y;
}
Big_num operator/(Big_num other){
string x=Div(num,other.num);
Big_num y=x;
return y;
}
Big_num operator%(Big_num other){
string x=Comple(num,other.num);
Big_num y=x;
return y;
}
};
string to_string(Big_num x){
return x.num;
}
ostream& operator<<(ostream& os,const Big_num& num){
os<<to_string(num);
return os;
}
istream& operator>>(istream& is,Big_num& num){
is>>num.num;
return is;
}
}
using namespace BIG_NUM;
继续优化了时间复杂度。
董安雅在2023-04-16 13:20:56追加了内容
#include<bits/stdc++.h>
using namespace std;
namespace BIG_NUM{
namespace BN{
int a[50005],b[50005],c[100005];
string k[50005];
string f[10];
string Plus(string x,string y);//加法
string Minus(string x,string y){//减法
if(x==y)return "0";
if(x[0]=='-'&&y[0]=='-'){
return Minus(y.substr(1,y.size()-1),
x.substr(1,y.size()-1));
}
else if(x[0]=='-'&&y[0]!='-'){
string t=Plus(x.substr(1,x.size()-1),y);
t="-"+t;
return t;
}
else if(x[0]!='-'&&y[0]=='-'){
return Plus(x,y.substr(1,y.size()-1));
}
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=max(a[0],b[0]);//c[0]存差的位数
for(int i=a[0]+1;i<=c[0];i++){
a[i]=0;
}
for(int i=b[0]+1;i<=c[0];i++){
b[i]=0;
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
if(a[i]<b[i]){//借位的情况
a[i+1]--;
a[i]+=10;
}
c[i]=a[i]-b[i];
}
while(c[c[0]]==0)c[0]--;//高位连续0的情况
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
return z;
}
string Plus(string x,string y){//加法
if(x[0]=='-'&&y[0]=='-'){
string t=Plus(x.substr(1,x.size()-1),
y.substr(1,y.size()-1));
t="-"+t;
return t;
}
else if(x[0]=='-'&&y[0]!='-'){
return Minus(y,x.substr(1,x.size()-1));
}
else if(x[0]!='-'&&y[0]=='-'){
return Minus(x,y.substr(1,y.size()-1));
}
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=max(a[0],b[0]);//c[0]存和的位数
for(int i=a[0]+1;i<=c[0];i++){
a[i]=0;
}
for(int i=b[0]+1;i<=c[0];i++){
b[i]=0;
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
c[i]=a[i]+b[i]+jw;
jw=c[i]/10;//先处理进位
c[i]%=10;
}
if(jw!=0)c[++c[0]]=jw;//判断是否进位,进位,位数+1,这一位为1
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
return z;
}
void Plus(){//加法
c[0]=max(a[0],b[0]);//c[0]存和的位数
for(int i=a[0]+1;i<=c[0];i++){
a[i]=0;
}
for(int i=b[0]+1;i<=c[0];i++){
b[i]=0;
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
c[i]=a[i]+b[i]+jw;
jw=c[i]/10;//先处理进位
c[i]%=10;
}
if(jw!=0)c[++c[0]]=jw;//判断是否进位,进位,位数+1,这一位为1
}
void Minus(){//减法
c[0]=max(a[0],b[0]);//c[0]存差的位数
for(int i=a[0]+1;i<=c[0];i++){
a[i]=0;
}
for(int i=b[0]+1;i<=c[0];i++){
b[i]=0;
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
if(a[i]<b[i]){//借位的情况
a[i+1]--;
a[i]+=10;
}
c[i]=a[i]-b[i];
}
while(c[c[0]]==0)c[0]--;//高位连续0的情况
}
string mobm(string x,char y){
vector<int> ans;
string t="";
int k=(int)y-48,len=x.size();
for(int i=len-1;i>=0;i--){
int num=((int)x[i]-48)*k;
if(ans.size()<len-i)ans.push_back(0);
ans[len-i-1]+=num%10;
ans.push_back(0);
ans[len-i]+=num/10;
}
while(ans.size()>1&&ans[ans.size()-1]==0){
ans.pop_back();
}
while(!ans.empty()){
t+=(char)(ans.back()+48);
ans.pop_back();
}
return t;
}
string azate(int len){
string ans="";
for(int i=1;i<=len;i++){
ans+="0";
}
return ans;
}
string Mul(string x,string y){
bool flag=false;
if(x[0]=='-'){
flag=!flag;
x.erase(0,1);
}
if(y[0]=='-'){
flag=!flag;
y.erase(0,1);
}
for(int i=0;i<10;i++){
f[i]="+_-INF";
}
f[0]="0",f[1]=y;
int len=x.size();
for(int i=len-1;i>=0;i--){
if(f[(int)x[i]-48]!="+_-INF"){
k[i]=f[(int)x[i]-48];
k[i]+=azate(len-i-1);
continue;
}
k[i]=mobm(y,x[i]);
k[i]+=azate(len-i-1);
}
string ans="";
c[0]=k[len-1].size();
for(int i=1;i<=c[0];i++){
c[i]=k[len-1][c[0]-i]-'0';
}
for(int i=len-2;i>=0;i--){
a[0]=c[0];
for(int j=1;j<=c[0];j++){
a[j]=c[j];
}
b[0]=k[i].size();
for(int j=1;j<=b[0];j++){
b[j]=k[i][b[0]-j]-'0';
}
Plus();
}
for(int i=c[0];i>=1;i--)ans=ans+(char)(c[i]+48);
ans=(flag==true?"-":"")+ans;
return ans;
}
bool check_size(string x,string y){
if(x.size()>y.size())return false;
else if(x.size()<y.size())return true;
else{
if(x>y)return false;
else{
return true;
}
}
}
class abnormal:public exception{
private:
string message;
public:
abnormal(string other){
message=other;
}
const char* what(){
return message.c_str();
}
};
string Div(string x,string y){
bool flag=false;
if(x[0]=='-'){
flag=!flag;
x.erase(0,1);
}
if(y[0]=='-'){
flag=!flag;
y.erase(0,1);
}
if(y=="0"){
abnormal e("Divider cannot be 0.");
throw e;
return "NULL";
}
else if(!check_size(y,x))return "0";
string ans="";
while(1){
string a=x.substr(0,y.size());
if(!check_size(y,a))a+=x[y.size()];
int l=0,r=9;
string k,k2;
while(l<r){
int mid=(l+r+1)/2;
k=Mul(y,to_string(mid));
if(check_size(k,a))l=mid;
else r=mid-1;
}
string t=to_string(l);
ans+=t;
k=x.substr(a.size(),x.size()-a.size()+1);
k2=Mul(y,t);
x=Minus(a,k2);
if(x=="0")x="";
int len=x.size();
x+=k;
if(k=="")break;
else if(!check_size(y,x)&&k.size()==1){
ans+="0";
break;
}
while(len<y.size()-1){
ans+="0";
len++;
}
while(!check_size(y,x.substr(0,len+1))){
ans+="0";
len++;
}
}
ans=(flag==true?"-":"")+ans;
return ans;
}
string Comple(string x,string y){
string t=Div(x,y);
string k=Minus(x,Mul(t,y));
return k;
}
}
class Big_num{
friend string to_string(Big_num x);
friend istream& operator>>(istream& is,Big_num& num);
private:
#define Plus(x,y) BN::Plus(x,y)
#define Minus(x,y) BN::Minus(x,y)
#define Mul(x,y) BN::Mul(x,y)
#define Div(x,y) BN::Div(x,y)
#define Comple(x,y) BN::Comple(x,y)
string num;
public:
Big_num(){
num="0";
}
Big_num(string other){
num=other;
}
Big_num(const char* other){
num=other;
}
Big_num(int other){
num=to_string(other);
}
Big_num(short other){
num=to_string((int)other);
}
Big_num(long other){
num=to_string(other);
}
Big_num(long long other){
num=to_string(other);
}
Big_num(const Big_num& other){
num=other.num;
}
Big_num& operator=(Big_num other){
num=other.num;
return *this;
}
Big_num operator+(Big_num other){
string x=Plus(num,other.num);
Big_num y=x;
return y;
}
Big_num operator-(Big_num other){
string x=Minus(num,other.num);
Big_num y=x;
return y;
}
Big_num operator*(Big_num other){
string x=Mul(num,other.num);
Big_num y=x;
return y;
}
Big_num operator/(Big_num other){
string x=Div(num,other.num);
Big_num y=x;
return y;
}
Big_num operator%(Big_num other){
string x=Comple(num,other.num);
Big_num y=x;
return y;
}
};
string to_string(Big_num x){
return x.num;
}
ostream& operator<<(ostream& os,const Big_num& num){
os<<to_string(num);
return os;
}
istream& operator>>(istream& is,Big_num& num){
is>>num.num;
return is;
}
}
using namespace BIG_NUM;
修复了一个BUG.
董安雅在2023-04-16 14:45:37追加了内容
#include<bits/stdc++.h>
using namespace std;
namespace BIG_NUM{
namespace BN{
int a[50005],b[50005],c[100005];
string k[50005];
string f[10];
string Plus(string x,string y);//加法
string Minus(string x,string y){//减法
if(x==y)return "0";
if(x[0]=='-'&&y[0]=='-'){
return Minus(y.substr(1,y.size()-1),
x.substr(1,y.size()-1));
}
else if(x[0]=='-'&&y[0]!='-'){
string t=Plus(x.substr(1,x.size()-1),y);
t="-"+t;
return t;
}
else if(x[0]!='-'&&y[0]=='-'){
return Plus(x,y.substr(1,y.size()-1));
}
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=max(a[0],b[0]);//c[0]存差的位数
for(int i=a[0]+1;i<=c[0];i++){
a[i]=0;
}
for(int i=b[0]+1;i<=c[0];i++){
b[i]=0;
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
if(a[i]<b[i]){//借位的情况
a[i+1]--;
a[i]+=10;
}
c[i]=a[i]-b[i];
}
while(c[c[0]]==0)c[0]--;//高位连续0的情况
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
return z;
}
string Plus(string x,string y){//加法
if(x[0]=='-'&&y[0]=='-'){
string t=Plus(x.substr(1,x.size()-1),
y.substr(1,y.size()-1));
t="-"+t;
return t;
}
else if(x[0]=='-'&&y[0]!='-'){
return Minus(y,x.substr(1,x.size()-1));
}
else if(x[0]!='-'&&y[0]=='-'){
return Minus(x,y.substr(1,y.size()-1));
}
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=max(a[0],b[0]);//c[0]存和的位数
for(int i=a[0]+1;i<=c[0];i++){
a[i]=0;
}
for(int i=b[0]+1;i<=c[0];i++){
b[i]=0;
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
c[i]=a[i]+b[i]+jw;
jw=c[i]/10;//先处理进位
c[i]%=10;
}
if(jw!=0)c[++c[0]]=jw;//判断是否进位,进位,位数+1,这一位为1
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
return z;
}
void Plus(){//加法
c[0]=max(a[0],b[0]);//c[0]存和的位数
for(int i=a[0]+1;i<=c[0];i++){
a[i]=0;
}
for(int i=b[0]+1;i<=c[0];i++){
b[i]=0;
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
c[i]=a[i]+b[i]+jw;
jw=c[i]/10;//先处理进位
c[i]%=10;
}
if(jw!=0)c[++c[0]]=jw;//判断是否进位,进位,位数+1,这一位为1
}
void Minus(){//减法
c[0]=max(a[0],b[0]);//c[0]存差的位数
for(int i=a[0]+1;i<=c[0];i++){
a[i]=0;
}
for(int i=b[0]+1;i<=c[0];i++){
b[i]=0;
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
if(a[i]<b[i]){//借位的情况
a[i+1]--;
a[i]+=10;
}
c[i]=a[i]-b[i];
}
while(c[c[0]]==0)c[0]--;//高位连续0的情况
}
string mobm(string x,char y){
vector<int> ans;
string t="";
int k=(int)y-48,len=x.size();
for(int i=len-1;i>=0;i--){
int num=((int)x[i]-48)*k;
if(ans.size()<len-i)ans.push_back(0);
ans[len-i-1]+=num%10;
ans.push_back(0);
ans[len-i]+=num/10;
}
while(ans.size()>1&&ans[ans.size()-1]==0){
ans.pop_back();
}
while(!ans.empty()){
t+=(char)(ans.back()+48);
ans.pop_back();
}
return t;
}
string azate(int len){
string ans="";
for(int i=1;i<=len;i++){
ans+="0";
}
return ans;
}
string Mul(string x,string y){
bool flag=false;
if(x[0]=='-'){
flag=!flag;
x.erase(0,1);
}
if(y[0]=='-'){
flag=!flag;
y.erase(0,1);
}
for(int i=0;i<10;i++){
f[i]="+_-INF";
}
f[0]="0",f[1]=y;
int len=x.size();
for(int i=len-1;i>=0;i--){
if(f[(int)x[i]-48]!="+_-INF"){
k[i]=f[(int)x[i]-48];
k[i]+=azate(len-i-1);
continue;
}
k[i]=mobm(y,x[i]);
k[i]+=azate(len-i-1);
}
string ans="";
c[0]=k[len-1].size();
for(int i=1;i<=c[0];i++){
c[i]=k[len-1][c[0]-i]-'0';
}
for(int i=len-2;i>=0;i--){
a[0]=c[0];
for(int j=1;j<=c[0];j++){
a[j]=c[j];
}
b[0]=k[i].size();
for(int j=1;j<=b[0];j++){
b[j]=k[i][b[0]-j]-'0';
}
Plus();
}
for(int i=c[0];i>=1;i--)ans=ans+(char)(c[i]+48);
ans=(flag==true?"-":"")+ans;
return ans;
}
bool check_size(string x,string y){
if(x.size()>y.size())return false;
else if(x.size()<y.size())return true;
else{
if(x>y)return false;
else{
return true;
}
}
}
class abnormal:public exception{
private:
string message;
public:
abnormal(string other){
message=other;
}
const char* what(){
return message.c_str();
}
};
string Div(string x,string y){
bool flag=false;
if(x[0]=='-'){
flag=!flag;
x.erase(0,1);
}
if(y[0]=='-'){
flag=!flag;
y.erase(0,1);
}
if(y=="0"){
abnormal e("Divider cannot be 0.");
throw e;
return "NULL";
}
else if(!check_size(y,x))return "0";
string ans="";
while(1){
string a=x.substr(0,y.size());
if(!check_size(y,a))a+=x[y.size()];
int l=0,r=9;
string k,k2;
while(l<r){
int mid=(l+r+1)/2;
k=Mul(y,to_string(mid));
if(check_size(k,a))l=mid;
else r=mid-1;
}
string t=to_string(l);
ans+=t;
k=x.substr(a.size(),x.size()-a.size()+1);
k2=Mul(y,t);
x=Minus(a,k2);
if(x=="0")x="";
int len=x.size();
x+=k;
if(k=="")break;
else if(!check_size(y,x)&&k.size()==1){
ans+="0";
break;
}
while(len<y.size()-1){
ans+="0";
len++;
}
while(!check_size(y,x.substr(0,len+1))){
ans+="0";
len++;
}
}
ans=(flag==true?"-":"")+ans;
return ans;
}
string Comple(string x,string y){
string t=Div(x,y);
string k=Minus(x,Mul(t,y));
return k;
}
}
class Big_num{
friend string to_string(Big_num x);
friend istream& operator>>(istream& is,Big_num& num);
private:
#define Plus(x,y) BN::Plus(x,y)
#define Minus(x,y) BN::Minus(x,y)
#define Mul(x,y) BN::Mul(x,y)
#define Div(x,y) BN::Div(x,y)
#define Comple(x,y) BN::Comple(x,y)
string num;
public:
Big_num(){
num="0";
}
Big_num(string other){
num=other;
}
Big_num(const char* other){
num=other;
}
Big_num(int other){
num=to_string(other);
}
Big_num(short other){
num=to_string((int)other);
}
Big_num(long other){
num=to_string(other);
}
Big_num(long long other){
num=to_string(other);
}
Big_num(const Big_num& other){
num=other.num;
}
Big_num& operator=(Big_num other){
num=other.num;
return *this;
}
Big_num operator+(Big_num other){
string x=Plus(num,other.num);
Big_num y=x;
return y;
}
Big_num& operator+=(Big_num other){
string x=Plus(num,other.num);
num=x;
return *this;
}
Big_num operator-(Big_num other){
string x=Minus(num,other.num);
Big_num y=x;
return y;
}
Big_num& operator-=(Big_num other){
string x=Minus(num,other.num);
num=x;
return *this;
}
Big_num operator*(Big_num other){
string x=Mul(num,other.num);
Big_num y=x;
return y;
}
Big_num& operator*=(Big_num other){
string x=Mul(num,other.num);
num=x;
return *this;
}
Big_num operator/(Big_num other){
string x=Div(num,other.num);
Big_num y=x;
return y;
}
Big_num& operator/=(Big_num other){
string x=Div(num,other.num);
num=x;
return *this;
}
Big_num operator%(Big_num other){
string x=Comple(num,other.num);
Big_num y=x;
return y;
}
Big_num& operator%=(Big_num other){
string x=Comple(num,other.num);
num=x;
return *this;
}
};
string to_string(Big_num x){
return x.num;
}
ostream& operator<<(ostream& os,const Big_num& num){
os<<to_string(num);
return os;
}
istream& operator>>(istream& is,Big_num& num){
is>>num.num;
return is;
}
}
using namespace BIG_NUM;
董安雅在2023-04-16 14:55:59追加了内容
#include<bits/stdc++.h>
using namespace std;
namespace BIG_NUM{
namespace BN{
int a[50005],b[50005],c[100005];
string k[50005];
string f[10];
string Plus(string x,string y);//加法
string Minus(string x,string y){//减法
if(x==y)return "0";
if(x[0]=='-'&&y[0]=='-'){
return Minus(y.substr(1,y.size()-1),
x.substr(1,y.size()-1));
}
else if(x[0]=='-'&&y[0]!='-'){
string t=Plus(x.substr(1,x.size()-1),y);
t="-"+t;
return t;
}
else if(x[0]!='-'&&y[0]=='-'){
return Plus(x,y.substr(1,y.size()-1));
}
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=max(a[0],b[0]);//c[0]存差的位数
for(int i=a[0]+1;i<=c[0];i++){
a[i]=0;
}
for(int i=b[0]+1;i<=c[0];i++){
b[i]=0;
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
if(a[i]<b[i]){//借位的情况
a[i+1]--;
a[i]+=10;
}
c[i]=a[i]-b[i];
}
while(c[c[0]]==0)c[0]--;//高位连续0的情况
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
return z;
}
string Plus(string x,string y){//加法
if(x[0]=='-'&&y[0]=='-'){
string t=Plus(x.substr(1,x.size()-1),
y.substr(1,y.size()-1));
t="-"+t;
return t;
}
else if(x[0]=='-'&&y[0]!='-'){
return Minus(y,x.substr(1,x.size()-1));
}
else if(x[0]!='-'&&y[0]=='-'){
return Minus(x,y.substr(1,y.size()-1));
}
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=max(a[0],b[0]);//c[0]存和的位数
for(int i=a[0]+1;i<=c[0];i++){
a[i]=0;
}
for(int i=b[0]+1;i<=c[0];i++){
b[i]=0;
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
c[i]=a[i]+b[i]+jw;
jw=c[i]/10;//先处理进位
c[i]%=10;
}
if(jw!=0)c[++c[0]]=jw;//判断是否进位,进位,位数+1,这一位为1
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
return z;
}
void Plus(){//加法
c[0]=max(a[0],b[0]);//c[0]存和的位数
for(int i=a[0]+1;i<=c[0];i++){
a[i]=0;
}
for(int i=b[0]+1;i<=c[0];i++){
b[i]=0;
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
c[i]=a[i]+b[i]+jw;
jw=c[i]/10;//先处理进位
c[i]%=10;
}
if(jw!=0)c[++c[0]]=jw;//判断是否进位,进位,位数+1,这一位为1
}
void Minus(){//减法
c[0]=max(a[0],b[0]);//c[0]存差的位数
for(int i=a[0]+1;i<=c[0];i++){
a[i]=0;
}
for(int i=b[0]+1;i<=c[0];i++){
b[i]=0;
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
if(a[i]<b[i]){//借位的情况
a[i+1]--;
a[i]+=10;
}
c[i]=a[i]-b[i];
}
while(c[c[0]]==0)c[0]--;//高位连续0的情况
}
string mobm(string x,char y){
vector<int> ans;
string t="";
int k=(int)y-48,len=x.size();
for(int i=len-1;i>=0;i--){
int num=((int)x[i]-48)*k;
if(ans.size()<len-i)ans.push_back(0);
ans[len-i-1]+=num%10;
ans.push_back(0);
ans[len-i]+=num/10;
}
while(ans.size()>1&&ans[ans.size()-1]==0){
ans.pop_back();
}
while(!ans.empty()){
t+=(char)(ans.back()+48);
ans.pop_back();
}
return t;
}
string azate(int len){
string ans="";
for(int i=1;i<=len;i++){
ans+="0";
}
return ans;
}
string Mul(string x,string y){
bool flag=false;
if(x[0]=='-'){
flag=!flag;
x.erase(0,1);
}
if(y[0]=='-'){
flag=!flag;
y.erase(0,1);
}
for(int i=0;i<10;i++){
f[i]="+_-INF";
}
f[0]="0",f[1]=y;
int len=x.size();
for(int i=len-1;i>=0;i--){
if(f[(int)x[i]-48]!="+_-INF"){
k[i]=f[(int)x[i]-48];
k[i]+=azate(len-i-1);
continue;
}
k[i]=mobm(y,x[i]);
k[i]+=azate(len-i-1);
}
string ans="";
c[0]=k[len-1].size();
for(int i=1;i<=c[0];i++){
c[i]=k[len-1][c[0]-i]-'0';
}
for(int i=len-2;i>=0;i--){
a[0]=c[0];
for(int j=1;j<=c[0];j++){
a[j]=c[j];
}
b[0]=k[i].size();
for(int j=1;j<=b[0];j++){
b[j]=k[i][b[0]-j]-'0';
}
Plus();
}
for(int i=c[0];i>=1;i--)ans=ans+(char)(c[i]+48);
ans=(flag==true?"-":"")+ans;
return ans;
}
bool check_size(string x,string y){
if(x.size()>y.size())return false;
else if(x.size()<y.size())return true;
else{
if(x>y)return false;
else{
return true;
}
}
}
class abnormal:public exception{
private:
string message;
public:
abnormal(string other){
message=other;
}
const char* what(){
return message.c_str();
}
};
string Div(string x,string y){
bool flag=false;
if(x[0]=='-'){
flag=!flag;
x.erase(0,1);
}
if(y[0]=='-'){
flag=!flag;
y.erase(0,1);
}
if(y=="0"){
abnormal e("Divider cannot be 0.");
throw e;
return "NULL";
}
else if(!check_size(y,x))return "0";
string ans="";
while(1){
string a=x.substr(0,y.size());
if(!check_size(y,a))a+=x[y.size()];
int l=0,r=9;
string k,k2;
while(l<r){
int mid=(l+r+1)/2;
k=Mul(y,to_string(mid));
if(check_size(k,a))l=mid;
else r=mid-1;
}
string t=to_string(l);
ans+=t;
k=x.substr(a.size(),x.size()-a.size()+1);
k2=Mul(y,t);
x=Minus(a,k2);
if(x=="0")x="";
int len=x.size();
x+=k;
if(k=="")break;
else if(!check_size(y,x)&&k.size()==1){
ans+="0";
break;
}
while(len<y.size()-1){
ans+="0";
len++;
}
while(!check_size(y,x.substr(0,len+1))){
ans+="0";
len++;
}
}
ans=(flag==true?"-":"")+ans;
return ans;
}
string Comple(string x,string y){
string t=Div(x,y);
string k=Minus(x,Mul(t,y));
return k;
}
}
class Big_num{
friend string to_string(Big_num x);
friend istream& operator>>(istream& is,Big_num& num);
private:
#define Plus(x,y) BN::Plus(x,y)
#define Minus(x,y) BN::Minus(x,y)
#define Mul(x,y) BN::Mul(x,y)
#define Div(x,y) BN::Div(x,y)
#define Comple(x,y) BN::Comple(x,y)
string num;
public:
Big_num(){
num="0";
}
Big_num(string other){
num=other;
}
Big_num(const char* other){
num=other;
}
Big_num(int other){
num=to_string(other);
}
Big_num(short other){
num=to_string((int)other);
}
Big_num(long other){
num=to_string(other);
}
Big_num(long long other){
num=to_string(other);
}
Big_num(const Big_num& other){
num=other.num;
}
Big_num& operator=(Big_num other){
num=other.num;
return *this;
}
Big_num operator+(Big_num other){
string x=Plus(num,other.num);
Big_num y=x;
return y;
}
Big_num& operator+=(Big_num other){
string x=Plus(num,other.num);
num=x;
return *this;
}
Big_num operator-(Big_num other){
string x=Minus(num,other.num);
Big_num y=x;
return y;
}
Big_num& operator-=(Big_num other){
string x=Minus(num,other.num);
num=x;
return *this;
}
Big_num operator*(Big_num other){
string x=Mul(num,other.num);
Big_num y=x;
return y;
}
Big_num& operator*=(Big_num other){
string x=Mul(num,other.num);
num=x;
return *this;
}
Big_num operator/(Big_num other){
string x=Div(num,other.num);
Big_num y=x;
return y;
}
Big_num& operator/=(Big_num other){
string x=Div(num,other.num);
num=x;
return *this;
}
Big_num operator%(Big_num other){
string x=Comple(num,other.num);
Big_num y=x;
return y;
}
Big_num& operator%=(Big_num other){
string x=Comple(num,other.num);
num=x;
return *this;
}
Big_num& operator++(){
num=Plus(num,"1");
return *this;
}
Big_num operator++(int){
Big_num old=num;
num=Plus(num,"1");
return old;
}
};
string to_string(Big_num x){
return x.num;
}
Big_num abs(Big_num x){
string y=to_string(x);
if(y[0]=='-')y.erase(0,1);
Big_num z=y;
return z;
}
Big_num fabs(Big_num x){
return abs(x);
}
ostream& operator<<(ostream& os,const Big_num& num){
os<<to_string(num);
return os;
}
istream& operator>>(istream& is,Big_num& num){
is>>num.num;
return is;
}
}
using namespace BIG_NUM;
加入了一些新函数、运算符
董安雅在2023-05-07 10:20:02追加了内容
#include<bits/stdc++.h>
using namespace std;
namespace BIG_NUM{
namespace BN{
int a[50005],b[50005],c[100005];
string k[50005];
string f[10];
/*
const double PI = acos(-1.0);
struct Complex {
double x, y;
Complex(double _x = 0.0, double _y = 0.0) {
x = _x;
y = _y;
}
Complex operator-(const Complex &b) const {
return Complex(x - b.x, y - b.y);
}
Complex operator+(const Complex &b) const {
return Complex(x + b.x, y + b.y);
}
Complex operator*(const Complex &b) const {
return Complex(x * b.x - y * b.y, x * b.y + y * b.x);
}
};
void change(Complex y[], int len) {
int i, j, k;
for (int i = 1, j = len / 2; i < len - 1; i++) {
if (i < j) std::swap(y[i], y[j]);
k = len / 2;
while (j >= k) {
j = j - k;
k = k / 2;
}
if (j < k) j += k;
}
}
void fft(Complex y[], int len, int on) {
change(y, len);
for (int h = 2; h <= len; h <<= 1) {
Complex wn(cos(2 * PI / h), sin(on * 2 * PI / h));
for (int j = 0; j < len; j += h) {
Complex w(1, 0);
for (int k = j; k < j + h / 2; k++) {
Complex u = y[k];
Complex t = w * y[k + h / 2];
y[k] = u + t;
y[k + h / 2] = u - t;
w = w * wn;
}
}
}
if (on == -1) {
for (int i = 0; i < len; i++) {
y[i].x /= len;
}
}
}
string Mul(string x,string y){//乘法
bool flag=false;
if(x[0]=='-'){
flag=!flag;
x.erase(0,1);
}
if(y[0]=='-'){
flag=!flag;
y.erase(0,1);
}
memset(a,0,sizeof(a));
memset(b,0,sizeof(b));
memset(c,0,sizeof(c));
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=a[0]+b[0];//积的位数
for(int i=1;i<=a[0];i++){
for(int j=1;j<=b[0];j++){
c[i+j-1]+=a[i]*b[j];//这里一定要+=
}
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
c[i]=c[i]+jw;
jw=c[i]/10;
c[i]%=10;
}
while(c[c[0]]==0)c[0]--;//高位连续0的情况
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
z=(flag==true?"-":"")+z;
return z;
}
*/
string Plus(string x,string y);//加法
string Minus(string x,string y){//减法
if(x==y)return "0";
if(x[0]=='-'&&y[0]=='-'){
return Minus(y.substr(1,y.size()-1),
x.substr(1,y.size()-1));
}
else if(x[0]=='-'&&y[0]!='-'){
string t=Plus(x.substr(1,x.size()-1),y);
t="-"+t;
return t;
}
else if(x[0]!='-'&&y[0]=='-'){
return Plus(x,y.substr(1,y.size()-1));
}
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=max(a[0],b[0]);//c[0]存差的位数
for(int i=a[0]+1;i<=c[0];i++){
a[i]=0;
}
for(int i=b[0]+1;i<=c[0];i++){
b[i]=0;
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
if(a[i]<b[i]){//借位的情况
a[i+1]--;
a[i]+=10;
}
c[i]=a[i]-b[i];
}
while(c[c[0]]==0)c[0]--;//高位连续0的情况
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
return z;
}
string Plus(string x,string y){//加法
if(x[0]=='-'&&y[0]=='-'){
string t=Plus(x.substr(1,x.size()-1),
y.substr(1,y.size()-1));
t="-"+t;
return t;
}
else if(x[0]=='-'&&y[0]!='-'){
return Minus(y,x.substr(1,x.size()-1));
}
else if(x[0]!='-'&&y[0]=='-'){
return Minus(x,y.substr(1,y.size()-1));
}
a[0]=x.size(),b[0]=y.size();//a[0] b[0]存位数
for(int i=1;i<=a[0];i++){//倒着存入数组
a[i]=x[a[0]-i]-'0';
}
for(int i=1;i<=b[0];i++){//倒着存入数组
b[i]=y[b[0]-i]-'0';
}
c[0]=max(a[0],b[0]);//c[0]存和的位数
for(int i=a[0]+1;i<=c[0];i++){
a[i]=0;
}
for(int i=b[0]+1;i<=c[0];i++){
b[i]=0;
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
c[i]=a[i]+b[i]+jw;
jw=c[i]/10;//先处理进位
c[i]%=10;
}
if(jw!=0)c[++c[0]]=jw;//判断是否进位,进位,位数+1,这一位为1
string z="";
for(int i=c[0];i>=1;i--)z=z+(char)(c[i]+48);//倒着放进字符串
return z;
}
void Plus(){//加法
c[0]=max(a[0],b[0]);//c[0]存和的位数
for(int i=a[0]+1;i<=c[0];i++){
a[i]=0;
}
for(int i=b[0]+1;i<=c[0];i++){
b[i]=0;
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
c[i]=a[i]+b[i]+jw;
jw=c[i]/10;//先处理进位
c[i]%=10;
}
if(jw!=0)c[++c[0]]=jw;//判断是否进位,进位,位数+1,这一位为1
}
void Minus(){//减法
c[0]=max(a[0],b[0]);//c[0]存差的位数
for(int i=a[0]+1;i<=c[0];i++){
a[i]=0;
}
for(int i=b[0]+1;i<=c[0];i++){
b[i]=0;
}
int jw=0;//jw初值0
for(int i=1;i<=c[0];i++){
if(a[i]<b[i]){//借位的情况
a[i+1]--;
a[i]+=10;
}
c[i]=a[i]-b[i];
}
while(c[c[0]]==0)c[0]--;//高位连续0的情况
}
string mobm(string x,char y){
vector<int> ans;
string t="";
int k=(int)y-48,len=x.size();
for(int i=len-1;i>=0;i--){
int num=((int)x[i]-48)*k;
if(ans.size()<len-i)ans.push_back(0);
ans[len-i-1]+=num%10;
ans.push_back(0);
ans[len-i]+=num/10;
}
while(ans.size()>1&&ans[ans.size()-1]==0){
ans.pop_back();
}
while(!ans.empty()){
t+=(char)(ans.back()+48);
ans.pop_back();
}
return t;
}
string azate(int len){
string ans="";
for(int i=1;i<=len;i++){
ans+="0";
}
return ans;
}
string Mul(string x,string y){
bool flag=false;
if(x[0]=='-'){
flag=!flag;
x.erase(0,1);
}
if(y[0]=='-'){
flag=!flag;
y.erase(0,1);
}
for(int i=0;i<10;i++){
f[i]="+_-INF";
}
f[0]="0",f[1]=y;
int len=x.size();
for(int i=len-1;i>=0;i--){
if(f[(int)x[i]-48]!="+_-INF"){
k[i]=f[(int)x[i]-48];
k[i]+=azate(len-i-1);
continue;
}
k[i]=mobm(y,x[i]);
k[i]+=azate(len-i-1);
}
string ans="";
c[0]=k[len-1].size();
for(int i=1;i<=c[0];i++){
c[i]=k[len-1][c[0]-i]-'0';
}
for(int i=len-2;i>=0;i--){
a[0]=c[0];
for(int j=1;j<=c[0];j++){
a[j]=c[j];
}
b[0]=k[i].size();
for(int j=1;j<=b[0];j++){
b[j]=k[i][b[0]-j]-'0';
}
Plus();
}
for(int i=c[0];i>=1;i--)ans=ans+(char)(c[i]+48);
ans=(flag==true?"-":"")+ans;
return ans;
}
bool check_size(string x,string y){
if(x.size()>y.size())return false;
else if(x.size()<y.size())return true;
else{
if(x>y)return false;
else{
return true;
}
}
}
class abnormal:public exception{
private:
string message;
public:
abnormal(string other){
message=other;
}
const char* what(){
return message.c_str();
}
};
string Div(string x,string y){
bool flag=false;
if(x[0]=='-'){
flag=!flag;
x.erase(0,1);
}
if(y[0]=='-'){
flag=!flag;
y.erase(0,1);
}
if(y=="0"){
abnormal e("Divider cannot be 0.");
throw e;
return "NULL";
}
else if(!check_size(y,x))return "0";
string ans="";
while(1){
string a=x.substr(0,y.size());
if(!check_size(y,a))a+=x[y.size()];
int l=0,r=9;
string k,k2;
while(l<r){
int mid=(l+r+1)/2;
k=Mul(y,to_string(mid));
if(check_size(k,a))l=mid;
else r=mid-1;
}
string t=to_string(l);
ans+=t;
k=x.substr(a.size(),x.size()-a.size()+1);
k2=Mul(y,t);
x=Minus(a,k2);
if(x=="0")x="";
int len=x.size();
x+=k;
if(k=="")break;
else if(!check_size(y,x)&&k.size()==1){
ans+="0";
break;
}
while(len<y.size()-1){
ans+="0";
len++;
}
while(!check_size(y,x.substr(0,len+1))){
ans+="0";
len++;
}
}
ans=(flag==true?"-":"")+ans;
return ans;
}
string Comple(string x,string y){
string t=Div(x,y);
string k=Minus(x,Mul(t,y));
return k;
}
}
class Big_num{
friend string to_string(Big_num x);
friend istream& operator>>(istream& is,Big_num& num);
private:
string num;
public:
Big_num(){
num="0";
}
Big_num(string other){
num=other;
}
Big_num(const char* other){
num=other;
}
Big_num(int other){
num=to_string(other);
}
Big_num(short other){
num=to_string((int)other);
}
Big_num(long other){
num=to_string(other);
}
Big_num(long long other){
num=to_string(other);
}
Big_num(const Big_num& other){
num=other.num;
}
Big_num& operator=(Big_num other){
num=other.num;
return *this;
}
Big_num operator+(Big_num other){
string x=BN::Plus(num,other.num);
Big_num y=x;
return y;
}
Big_num& operator+=(Big_num other){
string x=BN::Plus(num,other.num);
num=x;
return *this;
}
Big_num operator-(Big_num other){
string x=BN::Minus(num,other.num);
Big_num y=x;
return y;
}
Big_num& operator-=(Big_num other){
string x=BN::Minus(num,other.num);
num=x;
return *this;
}
Big_num operator*(Big_num other){
string x=BN::Mul(num,other.num);
Big_num y=x;
return y;
}
Big_num& operator*=(Big_num other){
string x=BN::Mul(num,other.num);
num=x;
return *this;
}
Big_num operator/(Big_num other){
string x=BN::Div(num,other.num);
Big_num y=x;
return y;
}
Big_num& operator/=(Big_num other){
string x=BN::Div(num,other.num);
num=x;
return *this;
}
Big_num operator%(Big_num other){
string x=BN::Comple(num,other.num);
Big_num y=x;
return y;
}
Big_num& operator%=(Big_num other){
string x=BN::Comple(num,other.num);
num=x;
return *this;
}
Big_num& operator++(){
num=BN::Plus(num,"1");
return *this;
}
Big_num operator++(int){
Big_num old=num;
num=BN::Plus(num,"1");
return old;
}
bool operator==(Big_num other){
return num==other.num;
}
bool operator!=(Big_num other){
return num!=other.num;
}
bool operator<(Big_num other){
return !BN::check_size(other.num,num);
}
bool operator>(Big_num other){
return !BN::check_size(num,other.num);
}
bool operator<=(Big_num other){
return BN::check_size(num,other.num);
}
bool operator>=(Big_num other){
return BN::check_size(other.num,num);
}
};
string to_string(Big_num x){
return x.num;
}
Big_num abs(Big_num x){
string y=to_string(x);
if(y[0]=='-')y.erase(0,1);
Big_num z=y;
return z;
}
Big_num fabs(Big_num x){
return abs(x);
}
ostream& operator<<(ostream& os,const Big_num& num){
os<<to_string(num);
return os;
}
istream& operator>>(istream& is,Big_num& num){
is>>num.num;
return is;
}
}
using namespace BIG_NUM;
此为最新代码,第九次更新!
董安雅在2023-05-07 11:23:04追加了内容
因没人关注,停止更新。
0
0
0
0
0
0
0
0
0
0