AGC 027 D Modulo Matrix
AGC 027 D Modulo Matrix
*构造
首先考虑黑白染色,黑格子放小的(除数)。
白格子的值就是\(k*p+1\),其中\(p\)为四周黑格子的lcm。
黑格子可以交错放置\(x,2x\)这样的数对,使得四个周围黑格子的值为\(O((n^6)/2^3)\)。
code:
/**
* author: gary
* created: 28.11.2021 09:28:47
**/
#include<bits/stdc++.h>
#define rb(a,b,c) for(int a=b;a<=c;++a)
#define rl(a,b,c) for(int a=b;a>=c;--a)
#define rep(a,b) for(int a=0;a<b;++a)
#define LL long long
#define PB push_back
#define POB pop_back
#define II(a,b) make_pair(a,b)
#define FIR first
#define SEC second
#define SRAND mt19937 rng(chrono::steady_clock::now().time_since_epoch().count())
#define random(a) rng()%a
#define ALL(a) a.begin(),a.end()
#define check_min(a,b) a=min(a,b)
#define check_max(a,b) a=max(a,b)
using namespace std;
const int INF=0x3f3f3f3f;
typedef pair<int,int> mp;
vector<mp> v;
unordered_map<LL,int> vis;
LL ans[505][505];
int walk[4][2]={
{0,1},
{0,-1},
{1,0},
{-1,0}
};
LL mygcd(LL A,LL B){
if(B==0) return A;
return mygcd(B,A%B);
}
int n;
bool check(int x,int y){
return min(x,y)>=1&&max(x,y)<=n;
}
int main(){
ios::sync_with_stdio(false);
cin.tie(0);
cin>>n;
int now=2;
for(int i=2;i<=n;i+=2){
while(vis[now]) now++;
vis[now]=1;
ans[i][1]=now;
}
vector<mp> tmp;
for(int i=1;i<=n;i+=2){
for(int j=2;j<=n;j+=2){
tmp.PB(II(0,0));
}
}
rep(i,tmp.size()){
while(vis[now]||vis[now*2]) now++;
tmp[i]=II(now,now*2);
vis[now]=vis[now*2]=1;
}
int l=0,r=tmp.size()-1;
for(int i=1;i<=n;i+=2){
int cnt=0;
for(int j=2;j<=n;j+=2){
cnt^=1;
if(cnt==0){
ans[i][j]=tmp[l].FIR;
if(check(i+1,j+1)) ans[i+1][j+1]=tmp[l].SEC;
l++;
}
else{
ans[i][j]=tmp[r].FIR;
if(check(i+1,j+1)) ans[i+1][j+1]=tmp[r].SEC;
r--;
}
}
}
rb(x,1,n){
rb(y,1,n){
if((x+y)%2==1) continue;
LL p;
p=1;
rep(k,4){
int nx,ny;
tie(nx,ny)=II(x+walk[k][0],y+walk[k][1]);
if(min(nx,ny)>=1&&max(nx,ny)<=n){
p=p/mygcd(p,ans[nx][ny])*ans[nx][ny];
}
}
// if(p<0){
// rep(k,4){
// int nx,ny;
// tie(nx,ny)=II(x+walk[k][0],y+walk[k][1]);
// if(min(nx,ny)>=1&&max(nx,ny)<=n){
// cout<<"("<<nx<<","<<ny<<")"<<ans[nx][ny]<<",";
// }
// }
// cout<<endl;
// cerr<<p<<" "<<x<<' '<<y<<endl;
// }
LL tmp=p+1;
while(vis.find(tmp)!=vis.end()){
tmp+=p;
}
ans[x][y]=tmp;
vis[tmp]=1;
}
}
LL mx=0,mn=1e18;
rb(i,1,n) rb(j,1,n) check_max(mx,ans[i][j]),check_min(mn,ans[i][j]);
// cerr<<mx<<","<<mn<<endl;
rb(i,1,n){
rb(j,1,n) cout<<ans[i][j]<<" ";
cout<<endl;
}
return 0;
}