萌新站外高精度题求条,玄关
查看原帖
萌新站外高精度题求条,玄关
910440
liujixuan2010118楼主2024/8/20 21:32

看了一晚上还是没看出来,感觉快疯了QwQ,哪位大佬能帮忙看一下

描述

给定三个非负整数 a,b,p 以及一个符号 op,请计算 (a op b)modp.

保证 op 一定为 +,-,*,/,^ 之一,分别表示加、减、乘、除与幂次,p 为素数。

请注意:计算 xmodp 时请将结果放到 [0,p−1] 内;op 为 / 时,可能需要用到逆元相关知识;op 为 ^ 时,可能需要用到快速幂操作来提高计算速度。

输入描述

输入共四行,前三行每行包含一个非负整数,分别表示 a,b,p.

第四行输入一个字符 op.

输出描述

输出一行,表示计算结果。

#include<bits/stdc++.h>
using namespace std;
const int N=1005;
struct HPN{
	int a[N];
	HPN(){
		memset(a,0,sizeof(a));
	}
	HPN(string s){
		a[0]=s.length();
		for(int i=1;i<=a[0];i++){
			a[i]=s[a[0]-i]-'0';
		}
	}
	HPN(int n){
		memset(a,0,sizeof(a));
		int k=n;
		do{
			a[++a[0]]=k%10;
			k/=10;
		}while(k>0);
	}
	void show(){
		for(int i=a[0];i>=1;i--){
			cout<<a[i];
		}
		cout<<endl;
	}
	int numcmp(int a[],int b[]){
		if(a[0]>b[0])return 1;
		else if(a[0]<b[0])return -1;
		else{
			for(int i=a[0];i>=1;i--){
				if(a[i]>b[i])return 1;
				else if(a[i]<b[i])return -1;
			}
			return 0;
		}
	}
	bool operator < (HPN b){
		return numcmp(a,b.a)<0;
	}
	bool operator == (HPN b){
		return numcmp(a,b.a)==0;
	}
	bool operator >= (HPN b){
		return numcmp(a,b.a)>=0;
	}
	void setLen(int i){//i为已知的大于等于数字位数的一个数字
		while(a[i]==0&&i>1){
			i--;
		}
		a[0]=i;
	}
	int& operator [] (int i){
		return a[i];
	}
	HPN operator + (HPN b){
		HPN r;
		int c=0;
		int i;
		for(i=1;i<=max(a[0],b[0]);++i){
			r[i]=a[i]+b[i]+c;
			c=r[i]/10;
			r[i]%=10;
		}
		r[i]=c;
		r.setLen(i);
		return r;
	}
	HPN operator - (HPN b){
		HPN r;
		int c=0;
		for(int i=1;i<=a[0];++i){
			r[i]=a[i]-b[i]-c;
			c=0;
			if(r[i]<0){
				c=1;
				r[i]+=10;
			}
		}
		r.setLen(a[0]);
		return r;
	}
	HPN operator * (int b){
		int c=0,i;
		HPN r;
		for(i=1;i<=a[0];i++){
			r[i]=a[i]*b+c;
			c=r[i]/10;
			r[i]%=10;
		}
		while(c>0){
			r[i++]=c%10;
			c/=10;
		}
		r.setLen(i);
		return r;
	}
	HPN operator * (HPN b){
		HPN r;
		for(int i=1;i<=a[0];++i){
			int c=0;
			for(int j=1;j<=b[0];++j){
				r[i+j-1]+=a[i]*b[j]+c;
				c=r[i+j-1]/10;
				r[i+j-1]%=10;
			}
			r[i+b[0]]+=c;
		}
		r.setLen(a[0]+b[0]);
		return r;
	}
	HPN operator / (int b){
		HPN r;
		int x=0;
		for(int i=a[0];i>=1;--i){
			r[i]=(x*10+a[i])/b;
			x=(x*10+a[i])%b;
		}
		r.setLen(a[0]);
		return r;
	}
	void addNum(int x){
		if(a[0]==1&&a[1]==0){
			a[1]=x;
		}else{
			for(int i=a[0];i>=1;i--){
				a[i+1]=a[i];
			}
			a[1]=x;
			a[0]++;
		}
	}
	HPN operator / (HPN b){
		HPN r,x(0);
		for(int i=a[0];i>=1;--i){
			int q=0;
			x.addNum(a[i]);
			while(x>=b){
				x=x-b;
				q++;
			}
			r[i]=q;
		}
		r.setLen(a[0]);
		return r;
	}
    HPN operator % (HPN di){
        HPN result;
        HPN div=*this/di;
        HPN mi=div*di;
        HPN mo=*this-mi;
        return mo;
    }
};
void exgcd(HPN a, HPN b, HPN &x, HPN &y){
	if(b==0){
		x=HPN(1),y=HPN(0);
		return;
	}
	exgcd(b,a%b,y,x);
	y=y-a/b*x;
}
HPN inv(HPN a,HPN m) {
    HPN x,y;
    exgcd(a,m,x,y);
    while(x<HPN(0)){
        x=x+m;
    }
    return x;
}
HPN fastPow(HPN base,HPN exp,HPN mod){
	if(exp==HPN(0)){
		return HPN(1);
	}
	if(exp%HPN(2)==1)fastPow(base*base%mod,exp/2,mod)*base;
	return fastPow(base*base%mod,exp/2,mod);
}
int main(){
	string s1,s2,s3;
	cin>>s1>>s2>>s3;
    HPN num1(s1),num2(s2),MOD(s3);
    HPN result;
    char op;
    cin>>op;
    switch(op){
		case '+':
			result=num1+num2;
		case '-':
			result=num1-num2;
		case '*':
			result=num1*num2;
		case '/':
			result=num1*inv(num2,MOD);//相当于乘逆元 
		case '^':
			result=fastPow(num1,num2,MOD);
    }
    result=(result%MOD+MOD)%MOD;
    result.show();
    return 0;
}
2024/8/20 21:32
加载中...