高斯整数环学习心得随笔及其实现
Posted hans774882968
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了高斯整数环学习心得随笔及其实现相关的知识,希望对你有一定的参考价值。
高斯整数环学习心得随笔
过些天补上~
代码
- ==:两个高斯整数相伴,即为相等。
- 小于和大于:用复数的范数Norm来比较。应用场景举例:高斯整数环的唯一分解定理证明。
- 整除和取模(带余除法):复数除法的结果是个有理数,但为了方便还是直接用double存了。设两个高斯整数
a,b
,复数除法结果为a / b = x+yi
,则一种可行的取法是round(x)+round(y)*i
,这就是整除结果。而g = (x-round(x))+(y-round(y))*i
就是带余除法定义中一个可行的“范数小于等于1/2的复数”,g*b
即取模结果。具体看代码。 - gcd:既然有带余除法,直接运行辗转相除法即可。
#include <bits/stdc++.h>
using namespace std;
typedef long long LL;
#define rep(i,a,b) for(int i = (a);i <= (b);++i)
#define re_(i,a,b) for(int i = (a);i < (b);++i)
#define dwn(i,a,b) for(int i = (a);i >= (b);--i)
const int N = 1e3 + 5;
const int mod = 998244353;
int dx[4] = -1,1,0,0,dy[4] = 0,0,-1,1;
void dbg()puts("");
template<typename T, typename... R>void dbg(const T &f, const R &... r)
cout << f << " ";
dbg(r...);
template<typename Type>inline void read(Type &xx)
Type f = 1;char ch;xx = 0;
for(ch = getchar();ch < '0' || ch > '9';ch = getchar()) if(ch == '-') f = -1;
for(;ch >= '0' && ch <= '9';ch = getchar()) xx = xx * 10 + ch - '0';
xx *= f;
void read()
template<typename T,typename ...R>void read(T &x,R &...r)
read(x);
read(r...);
struct GI;
LL norm(const GI &x);
GI gcd(const GI &x,const GI &y);
struct GI
int a,b;
GI():a(0),b(0)
GI(int a,int b):a(a),b(b)
//相伴
bool operator == (const GI &rh) const
return a == rh.a && b == rh.b ||
a == -rh.a && b == -rh.b ||
a == -rh.b && b == rh.a ||
a == rh.b && b == -rh.a;
bool operator < (const GI &rh) const
return norm(*this) < norm(rh);
bool operator <= (const GI &rh) const
return norm(*this) <= norm(rh);
bool operator > (const GI &rh) const
return norm(*this) > norm(rh);
bool operator >= (const GI &rh) const
return norm(*this) >= norm(rh);
GI operator + (const GI &rh) const
return a+rh.a,b+rh.b;
GI operator - (const GI &rh) const
return a-rh.a,b-rh.b;
GI operator * (const GI &rh) const
return a*rh.a-b*rh.b,a*rh.b+b*rh.a;
//整除
GI operator / (const GI &rh) const
double x = 1.0*(a*rh.a+b*rh.b)/norm(rh),y = 1.0*(b*rh.a-a*rh.b)/norm(rh);
return round(x),round(y);
GI operator % (const GI &rh) const
double x = 1.0*(a*rh.a+b*rh.b)/norm(rh),y = 1.0*(b*rh.a-a*rh.b)/norm(rh);
complex<double> g = x-round(x),y-round(y);
g *= complex<double>(rh.a,rh.b);
return round(g.real()),round(g.imag());
GI operator %= (const GI &rh)
GI u = (*this) % rh;
a = u.a;b = u.b;
return u;
friend ostream& operator << (ostream &sm,const GI &x)
sm << "(" << x.a << "," << x.b << ")";
return sm;
;
LL norm(const GI &x)return x.a*x.a+x.b*x.b;
GI gcd(const GI &x,const GI &y)
return y == GI() ? x : gcd(y,x%y);
void test_op()
dbg("test_op");
GI x(4,3),y(3,4);
assert(GI(4,3) == GI(-4,-3) && GI(4,3) == GI(-3,4) && GI(4,3) == GI(3,-4));
assert(!(x == y) && x <= y && x >= y);
GI z(4,4);
assert(x < z && x <= z && z > x && z >= x);
assert(x+y == GI(7,7));
assert(x*y == GI(0,25));
//对拍:https://jingyan.baidu.com/article/e75aca8526c6a7142fdac67f.html
void test_div()
dbg("test_div");
GI u = GI(1,8) % GI(-1,5);
dbg(u);//(-2,-3)
assert(u == GI(2,3));
GI x(18,5),y(7,5);
u = x - x / y * y;
dbg(x / y,u);//x / y = (2,-1), u = (-1,2)
dbg(x % y);//(-1,2)
assert(u == x % y);
dbg(y / u);//(1,-4)
dbg(y % u);//(0,-1)
x = 112,1;
y = -57,79;
dbg(x / y);//(-1,-1)
u = x % y;
dbg(u);//(-24,23)
assert(u == GI(-24,23));
x %= y;swap(x,y);
u = x % y;
dbg(u);//(-8,-14)
assert(u == GI(-8,-14));
x %= y;swap(x,y);
u = x % y;
dbg(u);//(-4,-7)
assert(u == GI(4,7));
void test_gcd()
dbg("test_gcd");
GI g = gcd(GI(18,5),GI(7,5));
dbg(g);//(0,-1)
assert(g == GI(0,-1));
g = gcd(GI(112,1),GI(-57,79));
dbg(g);//(-4,-7)
assert(g == GI(4,7));
g = gcd(GI(32,9),GI(4,11));
dbg(g);//(0,-1)
assert(g == GI(1,0));
g = gcd(GI(11,3),GI(1,8));
dbg(g);//(1,-2)
assert(g == GI(1,-2));
g = gcd(GI(4,5),GI(4,-5));
dbg(g);//(0,1)
assert(g == GI(1,0));
int main(int argc, char** argv)
test_op();
test_div();
test_gcd();
return 0;
以上是关于高斯整数环学习心得随笔及其实现的主要内容,如果未能解决你的问题,请参考以下文章