QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#791608 | #6746. Merge the Rectangles | HJR# | TL | 91ms | 136808kb | C++17 | 6.2kb | 2024-11-28 19:51:06 | 2024-11-28 19:51:08 |
Judging History
answer
#include<bits/stdc++.h>
using namespace std;
#include "ext/pb_ds/assoc_container.hpp"
using namespace __gnu_pbds;
#define endl "\n"
#define debug(x) cout<<#x<<": "<<x<<endl
mt19937_64 rng(chrono::steady_clock::now().time_since_epoch().count());
using ll=long long;
using ull=unsigned long long;
const int A=2*2250000;
const int N=1510,M=1510;
const int P=1e9+7;
int d[5][2]={{0,1},{1,0},{0,-1},{-1,0},{0,1}};
cc_hash_table<ull, vector<int>> mp;
cc_hash_table<ull,int> del;
vector<vector<int>> id(N,vector<int>(M));
vector<vector<int>> adj(N*M,vector<int>(4));
int n,m;
int tim=0;
int ctim=0;
vector<array<int,4>> allrec;
vector<array<ull,4>> rechs;
vector<ull> edg;
ull tran(int x,int y){
if(x>y)
swap(x,y);
return 1ull*x*P+y;
}
struct node
{
ull id;
vector<int> cmp;
bool operator<(const node&t)const{
return cmp.size()<t.cmp.size();
}
};
priority_queue<node> q;
void dl(int ci,int cj,int dir){
if(dir==0){
adj[id[ci][cj]][0]--;
adj[id[ci-1][cj]][2]--;
}
else if(dir==1){
adj[id[ci][cj]][1]--;
adj[id[ci][cj+1]][3]--;
}
else if(dir==2){
adj[id[ci][cj]][2]--;
adj[id[ci+1][cj]][0]--;
}
else{
adj[id[ci][cj]][3]--;
adj[id[ci][cj-1]][1]--;
}
}
void dfs(int i,int j){
array<int,4> now;
now[0]=id[i][j];
int flag=1;
adj[id[i][j]][1]--;
adj[id[i][j+1]][3]--;
int ci=i,cj=j+1;
while(1){
if(flag&&adj[id[ci][cj]][(flag+1)%4]){
dl(ci,cj,(flag+1)%4);
now[flag]=id[ci][cj];
ci+=d[flag][0],cj+=d[flag][1];
flag++;
if(flag==4)
flag=0;
}
else{
dl(ci,cj,flag);
if(flag)
ci+=d[flag-1][0],cj+=d[flag-1][1];
else
ci+=d[3][0],cj+=d[3][1];
}
if(ci==i&&cj==j){
break;
}
}
allrec.push_back(now);
rechs.push_back({});
for(int i=0;i<4;i++){
ull cur=tran(now[i],now[(i+1)%4]);
rechs[ctim][i]=cur;
edg.push_back(cur);
mp[cur].push_back(ctim);
}
ctim++;
}
void mergerec(int x,int y,ull cur){
for(int i=0;i<4;i++){
mp[rechs[x][i]].erase(find(mp[rechs[x][i]].begin(),mp[rechs[x][i]].end(),x));
mp[rechs[y][i]].erase(find(mp[rechs[y][i]].begin(),mp[rechs[y][i]].end(),y));
}
array<int,4> now;
for(int i=0;i<4;i++){
if(rechs[x][i]==cur){
if(i==0){
now[0]=allrec[y][0];
now[1]=allrec[y][1];
now[2]=allrec[x][2];
now[3]=allrec[x][3];
}
else if(i==1){
now[0]=allrec[x][0];
now[1]=allrec[y][1];
now[2]=allrec[y][2];
now[3]=allrec[x][3];
}
else if(i==2){
now[0]=allrec[x][0];
now[1]=allrec[x][1];
now[2]=allrec[y][2];
now[3]=allrec[y][3];
}
else{
now[0]=allrec[y][0];
now[1]=allrec[x][1];
now[2]=allrec[x][2];
now[3]=allrec[y][3];
}
}
}
del[cur]=1;
allrec.push_back(now);
rechs.push_back({});
for(int i=0;i<4;i++){
ull cur=tran(now[i],now[(i+1)%4]);
rechs[ctim][i]=cur;
edg.push_back(cur);
mp[cur].push_back(ctim);
q.push({cur,mp[cur]});
}
ctim++;
};
set<ull> yes;
void solve(){
cin>>n>>m;
for(int i=0;i<=n;i++){
for(int j=0;j<=m;j++){
id[i][j]=++tim;
}
}
for(int i=0,ci=1;i<n-1;i++,ci++){
string s;
cin>>s;
int cj=0;
for(auto x:s){
if(x=='1'){
adj[id[ci][cj]][1]=2;
adj[id[ci][cj+1]][3]=2;
}
cj++;
}
}
for(int i=0,ci=0;i<n;i++,ci++){
string s;
cin>>s;
int cj=1;
for(auto x:s){
if(x=='1'){
adj[id[ci][cj]][2]=2;
adj[id[ci+1][cj]][0]=2;
}
cj++;
}
}
for(int ci=0;ci<n;ci++){
adj[id[ci][0]][2]=1;
adj[id[ci+1][0]][0]=1;
adj[id[ci][m]][2]=1;
adj[id[ci+1][m]][0]=1;
}
for(int cj=0;cj<m;cj++){
adj[id[0][cj]][1]=1;
adj[id[0][cj+1]][3]=1;
adj[id[n][cj]][1]=1;
adj[id[n][cj+1]][3]=1;
}
for(int i=0;i<n;i++){
for(int j=0;j<m;j++){
if(adj[id[i][j]][1]>0){
dfs(i,j);
}
}
}
// sort(edg.begin(),edg.end());
// edg.erase(unique(edg.begin(),edg.end()),edg.end());
for(auto x:edg){
q.push({x,mp[x]});
}
yes.insert(tran(id[0][0],id[0][m]));
yes.insert(tran(id[0][m],id[n][m]));
yes.insert(tran(id[n][m],id[n][0]));
yes.insert(tran(id[n][0],id[0][0]));
while(!q.empty()){
ull cur=q.top().id;
vector<int> now=q.top().cmp;
q.pop();
int ok=1;
if(now!=mp[cur])
continue;
if(del[cur])
continue;
if(yes.count(cur)||mp[cur].size()==0)
continue;
if(mp[cur].size()<2){
cout<<"NO"<<endl;
return;
}
else{
mergerec(mp[cur][0],mp[cur][1],cur);
}
}
cout<<"YES"<<endl;
}
signed main(){
ios::sync_with_stdio(0);
cout.tie(0);
cin.tie(0);
int t=1;
while(t--){
solve();
}
}
/*
贡献法
正难则反
数小状压
关系连边
拆位
广义单调性
最长转最短
*/
详细
Test #1:
score: 100
Accepted
time: 87ms
memory: 136808kb
input:
3 4 0000 0111 101 101 110
output:
YES
result:
ok answer is YES
Test #2:
score: 0
Accepted
time: 59ms
memory: 136660kb
input:
3 3 110 011 01 11 10
output:
NO
result:
ok answer is NO
Test #3:
score: 0
Accepted
time: 91ms
memory: 136644kb
input:
1500 1500 00000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000000...
output:
YES
result:
ok answer is YES
Test #4:
score: -100
Time Limit Exceeded
input:
1500 1500 11111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111111...