Codeforces632F Magic Matrix

传送门

题目大意

给定一个 n×n 的矩阵,若满足以下条件则称其为Magic Matrix:

  1. ai,i=0.
  2. ai,j=aj,i.
  3. i,j,k, s.t.ai,jmax(ai,k,aj,k).

判断给出的矩阵是否为Magic.

1n2500,0ai,j<109.

题解

不会做….
据说随机化会被卡,各种推性质也过不了,tag里的分治以及图啊树啊的也不知道是什么鬼,官方题解啥都没说…

ShinFeb告诉我一种略无脑的做法,涨姿势了.
首先判掉前两个条件.
对于每个 ai,j ,如果存在 k 使得 ai,k,aj,k 都比它小,那么就不满足条件.
那么可以给所有三元组 (ai,j,i,j) 排个序,值相同的一起考虑,然后判前面是否有 k ,使得在 ai,aj 中都出现过.
这个可以用bitset压位无脑做….
这样做根本没有用到前两个条件对吧….

然后复杂度就是 O(n332) ,在CF上跑出 2s 多.

代码

#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#include 
#define fi first
#define se second
#define y1 kjfasiv
#define lowbit(x) (x&-x)
#define debug(x) cout<<#x<<"="<
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
typedef pair<int,int> pii;
typedef pair<int,pii> piii;
typedef pair pll;
const int mod=(int)1e9+7,INF=0x7fffffff,rx[]={-1,0,1,0},ry[]={0,1,0,-1};
const double pi=acos(-1.0),eps=1e-8;
void rd(int &res){
    res=0;
    char c;
    while(c=getchar(),c<48);
    do res=(res<<3)+(res<<1)+(c^48);
        while(c=getchar(),c>47);
}
inline void Max(int &a,int b){
    if(b>a)a=b;
}
inline void Min(int &a,int b){
    if(binline void mod_add(int &a,int b){
    if((a+=b)>=mod)a-=mod;
}
const int N=2505;
int n,num[N][N];
piii dat[N*N];
bitsetbs[N];
bool solve(){
    int tot=0;
    for(int i=0;iif(num[i][i])return false;
        for(int j=0;jif(num[i][j]!=num[j][i])return false;
            dat[tot++]=piii(num[i][j],pii(i,j));
        }
    }
    sort(dat,dat+tot);
    for(int i=0,j=0;ifor(++j;jfor(int k=i;kif((bs[P.fi]&bs[P.se]).any())return false;
        }
        for(int k=i;ktrue;
        }
    }
}
int main(){
    rd(n);
    for(int i=0;ifor(int j=0;jputs(solve()?"MAGIC":"NOT MAGIC");
    return 0;
}
/*

    Jul.12.16

    Tags:bitset
    Submissions:1

    Time 2277ms
    Memory 99000KB

*/

你可能感兴趣的:(题目解读,Codeforces,数据结构,---bitset)