CF632F Magic Matrix

V.CF632F Magic Matrix

暴 力 出 奇 迹

其限制可以被转化为,对于位置 ((i,j)),对其第 (i) 行和第 (j) 列的向量怼一块求个 (max) 后,所有位置的值都不小于 ((i,j)) 的值。

于是我们将所有元素按照从大到小排序,并按照上述次序依次枚举每个元素,将矩阵中所有不小于它的元素全都置为 (1),其它全都置为 (0)。则我们现在要判断的就是行向量和列向量的 ( ext{or}) 是否为全一向量。直接上 bitset 维护,复杂度 (O(dfrac{n^3}{omega}))

代码:

#include<bits/stdc++.h>
using namespace std;
int n;
int a[6250000],ord[6250000];
bitset<2500>N[2500],M[2500];
int main(){
	scanf("%d",&n);
	for(int i=0;i<n;i++)for(int j=0;j<n;j++)scanf("%d",&a[i*n+j]),ord[i*n+j]=i*n+j;
	sort(ord,ord+n*n,[](int u,int v){return a[u]>a[v];});
	for(int i=0;i<n;i++)if(a[i*n+i]){puts("NOT MAGIC");return 0;}
	for(int i=0;i<n;i++)for(int j=0;j<n;j++)if(a[i*n+j]!=a[j*n+i]){puts("NOT MAGIC");return 0;}
	for(int i=0,j=0;i<n*n;i=j){
		while(j<n*n&&a[ord[j]]==a[ord[i]])N[ord[j]/n][ord[j]%n]=1,M[ord[j]%n][ord[j]/n]=1,j++;
		for(int k=i;k<j;k++)if((N[ord[k]/n]|M[ord[k]%n]).count()!=n){puts("NOT MAGIC");return 0;}
	}
	puts("MAGIC");
	return 0;
}

原文地址:https://www.cnblogs.com/Troverld/p/14621822.html