题解 P3923 【大学数学题】
Updated On 2021/9/19. 笔者学了抽象代数之后,做了一些补充,同时修改了一些对专业术语的措辞。增加的地方加了P.S.。P.S.的部分比较难懂,若无法理解可以不看它们。不看P.S.的部分对全文理解不会有过多的影响。
一个有趣的抽象代数题。
开始我也是没有思路,于是就开始碰碰运气。我们先试一下-1:
case 6:case 143:cout<<"-1";break;
发现自己得了10分。对的是哪两个点呢?
第3和第14个,此时
于是我们不管这些合数了,只看素数的不小于1的整数幂。先观察素数:因为素数的完全剩余系与简化剩余系是相同的,我们直接把两个数相加并模这个素数即可。[P.S. 这里在有限域中即为:
case 3:case 19:case 89:case 181:case 233:
{
cout<<"0"<<endl;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cout<<(i+j)%n;
if(j==n-1)continue;
else cout<<' ';
}
cout<<endl;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cout<<(i*j)%n;
if(j==n-1)continue;
else cout<<' ';
}
cout<<endl;
}
}break;
于是就
后面怎么办呢?
我试了一个小时
if(n==4)
{
cout<<0<<endl;
cout<<"0 1 2 3\n1 0 3 2\n2 3 0 1\n3 2 1 0\n0 0 0 0\n0 1 2 3\n0 2 3 1\n0 3 1 2"<<endl;
return 0;
}
然后没有思绪。
于是在网上找"有限域",发现需要:
相加或相乘再模
这里,每个有限域中的数都是一个多项式的值的
找出一个系数在
再把它与原多项式相乘再模
但这个数已经大于
当然多项式也不好找,需要自己动脑筋。
下附所有
#include<bits/stdc++.h>
using namespace std;
#define N 17
int p;
struct f//多项式
{
int a[N];
int dr()
{
for(int i=N-1;i>=0;i--)
if(a[i]!=0) return i;
return 0;
}
inline void clr()
{
for(int i=0;i<N;i++) a[i]=0;
return;
}
inline void mod()
{
for(int i=0;i<N;i++) a[i]%=p;
return;
}
};
inline f mul(f x,int l)//数乘
{
for(int i=0;i<N;i++) x.a[i]*=l;
return x;
}
f gt(int x)//数转换为多项式
{
f ans;ans.clr();
for(int i=0;;i++)
{
if(x==0) return ans;
else{ans.a[i]=x%p;x/=p;}
}
}
int ungt(f ans)//多项式转为数
{
int x=0;
for(int i=ans.dr();i>=0;i--)
x=(x*p)+ans.a[i];
return x;
}
f add(f x,f y)//加
{
for(int i=0;i<=N;i++)
x.a[i]=(x.a[i]+y.a[i])%p;
return x;
}
f yiw(f x,int sum)//移位
{
for(int i=x.dr();i>=0;i--) x.a[i+sum]=x.a[i];
for(int i=sum-1;i>=0;i--) x.a[i]=0;
return x;
}
f prod(f x,f y)//多项式相乘
{
f ans;ans.clr();
for(int i=0;i<=x.dr();i++)
{
if(x.a[i]!=0) ans=add(ans,mul(yiw(y,i),x.a[i]));
}
ans.mod();
return ans;
}
f Mod(f x,f y)//多项式取模
{
int sg=y.dr()-1;
for(int i=x.dr();i>=sg+1;i--)
{
if(x.a[i]==0) continue;
else
{
x=add(x,mul(yiw(y,i-sg-1),p-x.a[i]));
x.mod();
}
}
return x;
}
f Num(int x)//找多项式
{
f ans;ans.clr();
if (x==8)ans.a[0]=ans.a[1]=ans.a[3]=1;
if (x==256) ans.a[8]=ans.a[4]=ans.a[3]=ans.a[1]=ans.a[0]=1;
if (x==16) ans.a[2]=ans.a[4]=ans.a[3]=ans.a[1]=ans.a[0]=1;
if (x==128) ans.a[7]=ans.a[6]=ans.a[5]=ans.a[2]=ans.a[0]=1;
return ans;
}
主函数内的:
case 256:case 128:case 8:
{
p=2;
cout<<0<<endl;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cout<<(i^j);
if(j==n-1)continue;
else cout<<' ';
}
cout<<endl;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
f x=gt(i);
f y=gt(j);
f z=prod(x,y);
z=Mod(z,Num(n));
int ans=ungt(z);
cout<<ans;
if(j==n-1)continue;
else cout<<' ';
}
cout<<endl;
}
}break;
最后,给出满分程序,但是多项式请自己找。
#include<bits/stdc++.h>
using namespace std;
#define N 17
int p;
struct f
{
int a[N];
int dr()
{
for(int i=N-1;i>=0;i--)
if(a[i]!=0) return i;
return 0;
}
inline void clr()
{
for(int i=0;i<N;i++) a[i]=0;
return;
}
inline void mod()
{
for(int i=0;i<N;i++) a[i]%=p;
return;
}
};
inline f mul(f x,int l)
{
for(int i=0;i<N;i++) x.a[i]*=l;
return x;
}
f gt(int x)
{
f ans;ans.clr();
for(int i=0;;i++)
{
if(x==0) return ans;
else{ans.a[i]=x%p;x/=p;}
}
}
int ungt(f ans)
{
int x=0;
for(int i=ans.dr();i>=0;i--)
x=(x*p)+ans.a[i];
return x;
}
f add(f x,f y)
{
for(int i=0;i<=N;i++)
x.a[i]=(x.a[i]+y.a[i])%p;
return x;
}
f yiw(f x,int sum)
{
for(int i=x.dr();i>=0;i--) x.a[i+sum]=x.a[i];
for(int i=sum-1;i>=0;i--) x.a[i]=0;
return x;
}
f prod(f x,f y)
{
f ans;ans.clr();
for(int i=0;i<=x.dr();i++)
{
if(x.a[i]!=0) ans=add(ans,mul(yiw(y,i),x.a[i]));
}
ans.mod();
return ans;
}
f Mod(f x,f y)
{
int sg=y.dr()-1;
for(int i=x.dr();i>=sg+1;i--)
{
if(x.a[i]==0) continue;
else
{
x=add(x,mul(yiw(y,i-sg-1),p-x.a[i]));
x.mod();
}
}
return x;
}
f Num(int x)
{
//自己找
}
int main()
{
ios::sync_with_stdio(0);
int n;
cin>>n;
if(n==4){cout<<0<<endl;cout<<"0 1 2 3\n1 0 3 2\n2 3 0 1\n3 2 1 0\n0 0 0 0\n0 1 2 3\n0 2 3 1\n0 3 1 2"<<endl;return 0;}
switch(n)
{
case 6:case 143:cout<<"-1";break;
case 3:case 19:case 89:case 181:case 233:
{
cout<<"0"<<endl;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cout<<(i+j)%n;
if(j==n-1)continue;
else cout<<' ';
}
cout<<endl;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cout<<(i*j)%n;
if(j==n-1)continue;
else cout<<' ';
}
cout<<endl;
}
}break;
case 256:case 128:case 8:
{
p=2;
cout<<0<<endl;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
cout<<(i^j);
if(j==n-1)continue;
else cout<<' ';
}
cout<<endl;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
f x=gt(i);
f y=gt(j);
f z=prod(x,y);
z=Mod(z,Num(n));
int ans=ungt(z);
cout<<ans;
if(j==n-1)continue;
else cout<<' ';
}
cout<<endl;
}
}break;
default:
{
p=...//自己写if
cout<<0<<endl;
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
f x=gt(i);
f y=gt(j);
f z=add(x,y);
int ans=ungt(z);
cout<<ans;
if(j==n-1)continue;
else cout<<' ';
}
cout<<endl;
}
for(int i=0;i<n;i++)
{
for(int j=0;j<n;j++)
{
f x=gt(i);
f y=gt(j);
f z=prod(x,y);
z=Mod(z,Num(n));
int ans=ungt(z);
cout<<ans;
if(j==n-1)continue;
else cout<<' ';
}
cout<<endl;
}
}
}
return 0;
}
P.S.
这里简略地证明一下有限域的元素个数必为
"环"的定义详见此。
环同态基本定理与群同态基本定理很类似。学过群论的应该都知道群同态基本定理,所以笔者认为不必介绍环的像、
设有限域为
定义1.设
引理1. 设
证明:反证法,设
引理2. 设
证明:定义映射
显然
反之,对
故断言成立。由环同态基本定理,