AGC027D - Modulo Matrix 题解


题目链接:D - Modulo Matrix

题目大意:洛谷


题解:考虑如下构造方案,对棋盘黑白染色,黑点填入两个质数的乘积,白点填入周围黑点的 \(\text{lcm} +1\) ,接下来只需要构造出一个黑点的填入方案即可。

考虑斜着的对角线(左上到右下和右上到左下都要考虑),每一个对角线对应一个质数,每一个黑点就是经过它的对角线的两个质数的乘积,然后随便调整一下顺序就可以满足要求,时间复杂度 \(O(n^2)\)

代码:

#include 
template
Elem gcd(Elem a,Elem b){
    if(b==0){
        return a;
    }
    return gcd(b,a%b);
}
template
Elem lcm(Elem a,Elem b){
    if(a==0||b==0){
        return a+b;
    }
    return a/gcd(a,b)*b;
}
typedef long long ll;
const int Maxn=500;
const int Maxv=10000;
const int d[4][2]={{0,1},{1,0},{0,-1},{-1,0}};
int n;
ll a[Maxn+5][Maxn+5];
bool np[Maxv+5];
int p[Maxv+5],p_len;
void init(){
    np[0]=np[1]=1;
    for(int i=2;i<=Maxv;i++){
        if(!np[i]){
            p[++p_len]=i;
            for(int j=i*i;j<=Maxv;j+=i){
                np[j]=1;
            }
        }
    }
}
int val_1[Maxn<<1|5],val_2[Maxn<<1|5];
int main(){
    init();
    scanf("%d",&n);
    if(n==2){
        puts("4 7");
        puts("23 10");
        return 0;
    }
    int id_tot=0;
    for(int i=2;i<=(n<<1);i+=2){
        val_1[i]=p[++id_tot];
    }
    int m;
    if(n&1){
        m=n+1;
        for(int i=(n<<1);i>0;i-=2){
            val_2[i]=p[++id_tot];
        }
    }
    else{
        m=n;
        for(int i=(n<<1)-2;i>0;i-=2){
            val_2[i]=p[++id_tot];
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if((i+j)&1){
                continue;
            }
            a[i][j]=1ll*val_1[i+j]*val_2[j-i+m];
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            if(!((i+j)&1)){
                continue;
            }
            for(int k=0;k<4;k++){
                int nx=i+d[k][0],ny=j+d[k][1];
                if(nx<1||ny<1||nx>n||ny>n){
                    continue;
                }
                a[i][j]=lcm(a[i][j],a[nx][ny]);
            }
            a[i][j]++;
        }
    }
    for(int i=1;i<=n;i++){
        for(int j=1;j<=n;j++){
            printf("%lld ",a[i][j]);
        }
        puts("");
    }
    return 0;
}