link。

调起来真的呕吐,网上又没篇题解。大概是个不错的题。

首先行和列一定是独立的,所以我们把行列分开考虑。这样的问题就弱化为:在一个长度为 \(n\) 的格子带上,有 \(n\) 个物品,每个物品 \(x\) 对应一个区间 \([l_x,r_x]\),分配每个物品的居所使得各住各的,求出其中的固定点。

把物品放在左部,把格子放在右部,即构造一个二部图。那么问题就是求出其最大匹配的必要边。先考虑如何求这个的最大匹配,这是个经典贪心吧,把每个区间按 \(l\) 排序,然后枚举位置,优先填入 \(r\) 小的物品。跑完后(即规定好方向后)对整个图跑缩点,两端点不在同一连通块的边即为必要边。

这个的边数是 \(O(n^2)\) 的,因为连边一下连一个区间,考虑利用这个来优化。线段树的高度不高吧,而且能够用来刻画一个区间,于是用这个东西来优化连边。

具体一点是,线段树上父亲对两个儿子连边,物品就对线段树上自己的区间连边即可。注意清空的时候带脑子……

#include<bits/stdc++.h>
using namespace std;
#define cmin(x, y) x = min(x, y)
#define cmax(x, y) x = max(x, y)
void eof(const char IO) {if(IO == -1) exit(0);}
template<typename T=int> T read() {
T x=0; char IO=getchar(); bool f=0; eof(IO);
while(IO<'0' || IO>'9') f|=IO=='-',eof(IO=getchar());
while(IO>='0' && IO<='9') x=x*10+(IO&15),eof(IO=getchar());
return f?-x:x;
}
int n,A[100100],B[100100],C[100100],D[100100],rec1[100100],rec2[100100],tot,ans1[100100],ans2[100100];
int col[400100],dfn[400100],low[400100],dfsnt,colnt,sta[400100],top,mat[400100],inst[400100];
priority_queue<pair<int, int>, vector<pair<int, int>>, greater<pair<int, int>>> q;
struct node{
int l,r,id;
friend bool operator<(const node& x,const node& y) {return x.l < y.l;}
} cur[100100];
vector<node> ans;
vector<vector<int>> e;
void DFS(const int now) {
inst[sta[++top] = now] = 1;
dfn[now] = low[now] = ++dfsnt;
for(const int y : e[now]) {
if(!dfn[y]) DFS(y),cmin(low[now], low[y]);
else if(inst[y]) cmin(low[now], dfn[y]);
}
if(low[now]^dfn[now]) return;
colnt++;
int y; do {
inst[y = sta[top--]] = 0;
col[y] = colnt;
} while(y != now);
}
#define mem(x, w, n) memset(x, w, n)
void sweep() {
e.clear();
mem(col, 0, min(size_t(n*4*30), sizeof(col)));
mem(dfn, 0, min(size_t(n*4*30), sizeof(dfn)));
mem(low, 0, min(size_t(n*4*30), sizeof(low)));
mem(sta, 0, min(size_t(n*4*30), sizeof(sta)));
mem(inst, 0, min(size_t(n*4*30), sizeof(inst)));
mem(mat, 0, min(size_t(n*4*30), sizeof(mat)));
// puts("DEBUGGING ----------");
// for(int* i : {col, dfn, low, sta, inst}) {
// for(int j = 0; j < 233; ++j) printf(" %d",i[j]);
// puts("");
// }
// puts("END___D__D__D____D___D_");
tot = dfsnt = colnt = top = 0;
while(q.size()) q.pop();
}
int tr[400100],reid[400100];
void addedge(const int one, const int ano) {
// printf("add:%d %d\n",one,ano);
if(one >= int(e.size())) e.resize(one+1);
e[one].push_back(ano);
}
void build(const int now, int l, int r) {
// printf(" %d %d\n",l,r);
tr[now] = ++tot;
if(l == r) return reid[l] = tot,void();
int mid = (l+r)>>1;
build(now<<1, l, mid),build(now<<1|1, mid+1, r);
addedge(tr[now], tr[now<<1]),addedge(tr[now], tr[now<<1|1]);
}
void lin(int x,int y,int k,const int now = 1,int l = 1,int r = n) {
if(l>y || r<x || x>y) return;
if(l>=x && r<=y) return addedge(k, tr[now]),void();
int mid = (l+r)>>1;
lin(x, y, k, now<<1, l, mid),lin(x, y, k, now<<1|1, mid+1, r);
}
bool solve(int rec[], int ans[]) {
sweep();
static int l[100100], r[100100];
for(int i=1; i<=n; ++i) l[i] = cur[i].l,r[i] = cur[i].r;
sort(cur + 1, cur + n + 1);
for(int i=1, p=1; i<=n; ++i) {
while(p <= n && cur[p].l <= i) q.emplace(cur[p].r, cur[p].id),p++;
if(!q.size() || q.top().first<i) return 0;
mat[q.top().second] = i;
q.pop();
}
tot = n;
build(1, 1, n);
// printf(" tot: %d\n", tot);
// for(int i=1; i<=4*n; ++i) printf(" %d",tr[i]);
// puts("");
for(int i=1; i<=n; ++i) {
addedge(reid[mat[i]], i);
lin(l[i], mat[i]-1, i);
lin(mat[i]+1, r[i], i);
}
for(int i=1; i<=tot; ++i) if(!dfn[i]) DFS(i);
// for(int i=1; i<=tot; ++i) printf(" %d",col[i]);
for(int i=1; i<=n; ++i) rec[i] = col[i] != col[reid[mat[i]]],ans[i] = mat[i];
return 1;
}
signed main() {
while(n = read(),233) {
for(int i=1; i<=n; ++i) A[i] = read(),B[i] = read(),C[i] = read(),D[i] = read();
for(int i=1; i<=n; ++i) cur[i] = (node){A[i], C[i], i};
if(!solve(rec1, ans1)) {
puts("-1");
goto Fail;
}
for(int i=1; i<=n; ++i) cur[i] = (node){B[i], D[i], i};
if(!solve(rec2, ans2)) {
puts("-1");
goto Fail;
}
vector<node>().swap(ans);
for(int i=1; i<=n; ++i) if(rec1[i] && rec2[i]) ans.push_back((node){i, ans1[i], ans2[i]});
cout<<ans.size()<<endl;
for(const auto [x, y, z] : ans) printf("%d %d %d\n", x, y, z);
Fail:;
}
return 0;
}

「openjudge / poj - 1057」Chessboard的更多相关文章

  1. 「POJ 3666」Making the Grade 题解(两种做法)

    0前言 感谢yxy童鞋的dp及暴力做法! 1 算法标签 优先队列.dp动态规划+滚动数组优化 2 题目难度 提高/提高+ CF rating:2300 3 题面 「POJ 3666」Making th ...

  2. LOJ6003 - 「网络流 24 题」魔术球

    原题链接 Description 假设有根柱子,现要按下述规则在这根柱子中依次放入编号为的球. 每次只能在某根柱子的最上面放球. 在同一根柱子中,任何2个相邻球的编号之和为完全平方数. 试设计一个算法 ...

  3. 对于前端,「微信小程序」其实不美好

    微信小程序开放公测了,9月底我曾经写过一篇 「微信小程序」来了,其中最后一句:"谢天谢地,我居然还是个前端". 这种火爆的新事物总是令人激动,感谢这个时代. 但是,当我真作为开发者 ...

  4. macOS安装「oh my zsh」

    目前常用的 Linux 系统和 OS X 系统的默认 Shell 都是 bash,但是真正强大的 Shell 是深藏不露的 zsh, 这货绝对是马车中的跑车,跑车中的飞行车,史称『终极 Shell』, ...

  5. 报名|「OneAPM x DaoCloud」技术公开课:Docker性能监控!

    如今,越来越多的公司开始 Docker 了,「三分之二的公司在尝试了 Docker 后最终使用了它」,也就是说 Docker 的转化率达到了 67%,同时转化时长也控制在 60 天内. 既然 Dock ...

  6. 企业运营对 DevOps 的「傲慢与偏见」

    摘要:出于各种原因,并非所有人都信任 DevOps .有些人觉得 DevOps 只不过给开发者改善产品提供了一个途径而已,还有的人觉得 DevOps 是一堆悦耳的空头支票,甚至有人认为 DevOps ...

  7. 「前端开发者」如何把握住「微信小程序」这波红利?

    由于前两周一直在老家处理重要事情,虽然朋友圈被「微信小程序」刷爆了,但并没有时间深入了解. 昨天回广州之后,第一件事情就是把「微信小程序」相关的文章.开发文档.设计规范全部看了一遍,基本上明白了「微信 ...

  8. 「花田对」CSDN程序员专场——谁来拯救技术宅!_豆瓣

    「花田对」CSDN程序员专场--谁来拯救技术宅!_豆瓣 「花田对」CSDN程序员专场--谁来拯救技术宅!

  9. Objective-C 实用关键字详解1「面试、工作」看我就 🐒 了 ^_^.

    在写项目 或 阅读别人的代码(一些优秀的源码)中,总能发现一些常见的关键字,随着编程经验的积累大部分还是知道是什么意思 的. 相信很多开发者跟我当初一样,只是基本的常用关键字定义属性会使用,但在关键字 ...

  10. LOJ6002 - 「网络流 24 题」最小路径覆盖

    原题链接 Description 求一个DAG的最小路径覆盖,并输出一种方案. Solution 模板题啦~ Code //「网络流 24 题」最小路径覆盖 #include <cstdio&g ...

随机推荐

  1. 有关 python 切片的趣事

    哈喽大家好,我是咸鱼 今天来讲一个我在实现 python 列表切片时遇到的趣事 在正式开始之前,我们先来了解一下切片(slice) 切片操作是访问序列(列表.字符串......)中元素的另一种方法,它 ...

  2. 02. vmware搭建centos虚拟机并使用静态ip,局域网内可互通

    一.虚拟机镜像地址 我这里有镜像 二.目的 使用vmware搭建centos虚拟机集群,进行基础服务搭建,对系统业务提供服务支撑 三.效果 centos虚拟机ip不会自动改变,使用设置的静态ip,可以 ...

  3. Zabbix Timeout 设置不当导致的问题

    哈喽大家好,我是咸鱼 今天跟大家分享一个关于 zabbix Timeout 值设置不当导致的问题,这个问题不知道大家有没有碰到过 问题 事情经过是这样的: 把某一台 zabbix agent 的模板由 ...

  4. 国产开源流批统一的数据同步工具Chunjun入门实战

    @ 目录 概述 定义 特性 部署 安装 版本对应关系 通用配置详解 整体配置 Content 配置 Setting 配置 Local提交 Standalone提交 Json方式使用 SQL方式使用 M ...

  5. 【Docker】离线安装

    离线安装Docker 1.下载docker 离线安装包 ​ 下载地址如下:Index of linux/static/stable/x86_64/ 2.将下载的包上传至服务器上 我这里下载的是20.1 ...

  6. [NOIP2011 提高组] 聪明的质监员【题解】

    题目 小 T 是一名质量监督员,最近负责检验一批矿产的质量.这批矿产共有 \(n\) 个矿石,从 \(1\) 到 \(n\) 逐一编号,每个矿石都有自己的重量 \(w_i\) 以及价值 \(v_i\) ...

  7. Vue-treeselect 实现下拉树懒加载,末节点不要箭头

    项目需要,可选择的下拉树,由于数据过多,显示要有层级感,所以使用了懒加载模式 vue-treeselect官网:https://www.vue-treeselect.cn/ 1.前端代码 1.下载依赖 ...

  8. linux 脚本:iptables-nat.sh

    #!/bin/bash # 2022.2.28 by dewan # DNAT configuration. iptables -t nat -F PUB_IFACE="enp125s0f0 ...

  9. 【技术积累】Linux中的命令行【理论篇】【一】

    7z命令 命令介绍 7z命令是Linux系统中的一个压缩和解压缩工具,它可以用来创建.压缩和解压缩7z格式的文件.7z是一种高压缩率的文件格式,通常比其他常见的压缩格式(如zip和gzip)具有更高的 ...

  10. React: Warning: `value` prop on `input` should not be null.

    警告 解决方案 对value进行判断 修改后的效果 至此问题解决