CF1844E题解
mod998244353 · · 题解
有一个套路是,只要确定第一行和第一列内填的字母,你就可以确定整个矩阵。
所以有个自然的想法是把矩阵中格子的关系转换为第一行和第一列内格子的关系。
假设我们不填字母,改填数字
不妨设左上角为
瞪眼看这四个矩阵,发现对于一个合法的矩阵
- 给定
(x,y) ,要求a_{x,y+1}=a_{x+1,y}
考虑分析子矩阵
对于第一种限制类型,
对于第二种限制类型,
那么我们就直接
因为
时间复杂度为
#include<bits/stdc++.h>
using namespace std;
const int MAXN=200005;
inline int read() {
static int x=0,c=getchar(),f=1;
for(f=1; c<=47||c>=58; c=getchar())f=f&&c^45;
for(x=0; c>=48&&c<=57; c=getchar())x=(x<<3)+(x<<1)+(c&15);
return f?x:-x;
}
vector<pair<int,int>>vec[MAXN];
int n,m,k,col[MAXN],ans;
void dfs(int u,int c) {
if(col[u]!=-1) {
if(col[u]^c) ans=0;
return;
}
col[u]=c;
for(pair<int,int>tmp:vec[u])
dfs(tmp.first,tmp.second^c);
}
inline void solve() {
n=read(),m=read(),k=read();
for(int i=1,x,y,xx,yy,u,v,w; i<=k; ++i) {
x=read(),y=read(),xx=read(),yy=read();
u=min(x,xx),v=n-1+min(y,yy),w=x+y!=xx+yy;
vec[u].push_back(make_pair(v,w)),vec[v].push_back(make_pair(u,w));
}
ans=1;
for(int i=1; i<=n+m-2; ++i) col[i]=-1;
for(int i=1; i<=n+m-2&&ans; ++i)
if(col[i]==-1)
dfs(i,0);
printf(ans?"YES\n":"NO\n");
for(int i=1; i<=n+m-2; ++i)vec[i].clear();
}
int main() {
int t=read();
while(t--)solve();
return 0;
}