1. 程式人生 > 其它 >AGC 027 D Modulo Matrix

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;
}