CSP-S 复习 ---- 高精度全家桶

v e c t o r vector vector 实现,高精除高精没有写,口胡
取模的时候重载 < < <,然后 ∗ 10 *10 10 相当于在最前面插一个数字,然后高精减就可以取模
除法更取模插不多,暴力减就可以了
乘法用了 F F T FFT FFT

#include<bits/stdc++.h>
#define cs const
using namespace std;
#define poly vector<int> 
cs int N = 4e5 + 5;
cs double PI = acos(-1.0);
struct node{
	double x, y; 
	node(double _x = 0, double _y = 0){ x = _x; y = _y; }
	node operator + (cs node &a){ return node(x + a.x, y + a.y); }
	node operator - (cs node &a){ return node(x - a.x, y - a.y); }
	node operator * (cs node &a){ return node(x * a.x - y * a.y, x * a.y + y * a.x); }  
}f[N], g[N]; 
int bit, up, rev[N];
void init(int len){ 
	bit = 0; up = 1; while(up <= len) up <<= 1, bit++;
	for(int i = 0; i < up; i++) rev[i] = (rev[i>>1]>>1) | ((i&1) << (bit-1)); 
}
void FFT(node *a, int typ){
	for(int i = 0; i < up; i++) if(i < rev[i]) swap(a[i], a[rev[i]]);
	for(int i = 1; i < up; i <<= 1){
		node wn(cos(PI / i), typ * sin(PI / i));
		for(int j = 0; j < up; j += (i<<1)){
			node w(1, 0);
			for(int k = 0; k < i; k++, w = w * wn){
				node x = a[k+j], y = a[k+j+i] * w;
				a[k+j] = x + y; a[k+j+i] = x - y;
			}
		}
	}
}
struct Bignum{
	poly a; int flg; // + -  
	#define pb push_back
	friend Bignum Mul(Bignum A, Bignum B){
		Bignum C;
		int n = A.a.size(), m = B.a.size();
		int len = n + m - 1; init(len);
		for(int i = 0; i < up; i++) f[i] = g[i] = node(0, 0);
		for(int i = 0; i < n; i++) f[i].x = A.a[i];
		for(int i = 0; i < m; i++) g[i].x = B.a[i];
		FFT(f, 1); FFT(g, 1); 
		for(int i = 0; i < up; i++) f[i] = f[i] * g[i];
		FFT(f, -1);
		for(int i = 0; i < up; i++){
			int v = (int)(f[i].x / up + 0.5);
			C.a.pb(v);
		} C.a.resize(len); return C;
	}
	friend Bignum operator + (Bignum A, Bignum B){
		Bignum C; int len = max(A.a.size(), B.a.size());
		A.a.resize(len); B.a.resize(len); C.a.resize(len + 1);
		for(int i = 0; i < len; i++){
			C.a[i] += A.a[i] + B.a[i];
			if(C.a[i] >= 10) C.a[i] -= 10, C.a[i + 1]++;
		} if(!C.a[len]) C.a.resize(len); return C;
	}
	friend bool operator == (Bignum A, Bignum B){
		if(A.a.size() != B.a.size()) return false;
		for(int i = A.a.size() - 1; i >= 0; i--){
			if(A.a[i] != B.a[i]) return false;
		} return true;
	}
	friend bool operator < (Bignum A, Bignum B){
		if(A.a.size() != B.a.size()) return A.a.size() < B.a.size();
		for(int i = A.a.size() - 1; i >= 0; i--){
			if(A.a[i] != B.a[i]) return A.a[i] < B.a[i]; 
		} 
	} 
	friend Bignum operator - (Bignum A, Bignum B){
		Bignum C;
		if(A == B){ C.a.pb(0); return C;}
		if(A < B) swap(A, B), C.flg = -1;
		int len = A.a.size();
		C.a.resize(len); B.a.resize(len);
		for(int i = 0; i < len; i++){
			C.a[i] += A.a[i] - B.a[i];
			if(C.a[i] < 0) C.a[i] += 10, C.a[i + 1]--; 
		} while(!C.a[C.a.size() - 1]) C.a.pop_back(); return C;
	}
	friend Bignum operator * (Bignum A, Bignum B){
		Bignum C; int len = A.a.size() + B.a.size();
		if(len <= 512){
			C.a.resize(len); 
			for(int i = 0; i < A.a.size(); i++){
				for(int j = 0; j < B.a.size(); j++){
					C.a[i + j] += A.a[i] * B.a[j];
				}
			} 
		} 
		else{ C = Mul(A, B); C.a.resize(len); }
		for(int i = 0; i < C.a.size(); i++){
			if(C.a[i] >= 10){
				int k = C.a[i] / 10;
				C.a[i] -= k * 10;
				C.a[i + 1] += k; 
			} 
		} if(!C.a[len - 1]) C.a.pop_back(); return C;
	}
	friend int operator % (Bignum A, int b){
		int nx = 0;
		for(int i = A.a.size() - 1; i >= 0; i--){
			nx = (nx * 10 + A.a[i]) % b;
		} return nx;
	}
	friend Bignum operator / (Bignum A, int b){
		Bignum B; int len = A.a.size(), nx = 0;
		for(int i = len - 1; i >= 0; i--){
			nx = nx * 10 + A.a[i];
			if(nx >= b){
				int k = nx / b; B.a.pb(k); 
				nx -= k * b;
			} else if(B.a.size()) B.a.pb(0);
		} reverse(B.a.begin(), B.a.end()); return B;
	}
	void read(){
		char ch = 0; 
		while(!isdigit(ch)) ch = getchar();
		while(isdigit(ch)) a.pb(ch - '0'), ch = getchar();
		reverse(a.begin(), a.end()); // 小的位在前面  
	}
	void print(){ if(flg == -1) putchar('-'); for(int i = a.size()-1; i >= 0; i--) cout << a[i]; }
}A, B; int x;
int main(){
	A.read(); B.read(); 
	(A + B).print(); puts("");
	(A - B).print(); puts("");
	(A * B).print(); puts("");
	A.read(); scanf("%d", &x);
	int y = A % x, ans = y; 
	while(y) B.a.push_back(y % 10), y /= 10; A = A - B;
	(A / x).print(); puts(""); cout << ans << '\n'; 
	return 0; 
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
CSP-S222是一个自测系统,它的主要目的是帮助用户评估和测试自己的计算机科学知识和能力。这个系统由中国计算机学会(CSP)开发,并且针对计算机科学相关的专业课程。 CSP-S222自测系统提供了一系列的问题和题目,涵盖了计算机科学的各个方面,例如算法、数据结构、编程语言、操作系统、数据库等。用户可以通过回答这些问题进行自我评估,了解自己在这些方面的水平和能力。 使用CSP-S222进行自测非常简单。用户可以通过注册并登录系统,然后选择相应的题目进行回答。这些题目既有选择题,也有编程题。用户可以根据自己的实际情况,选择合适的题目进行回答。在回答问题的过程中,系统会根据用户的答案自动评分,并提供相应的反馈和解析,帮助用户检查和纠正错误。 CSP-S222自测系统的好处是帮助用户系统地了解自己在计算机科学方面的知识和能力。通过自测,用户可以发现自己的薄弱环节,并针对性地进行学习和提高。此外,CSP-S222还提供了一些参考资料和学习资源,帮助用户进一步深入学习和掌握计算机科学相关的知识。 总之,CSP-S222自测系统是一个方便、实用的工具,可以帮助用户评估和测试自己在计算机科学方面的知识和能力。通过自测,用户可以更好地了解自己的水平,并进行针对性的学习和提高。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

FSYo

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值