CF650C Table Compression
给一个 \(n\times m\) 的非负整数矩阵 \(a\),让你求一个 \(n\times m\) 的非负整数矩阵 \(b\),满足以下条件
- 若 \(a_{i,j}<a_{i,k}\),则 \(b_{i,j}<b_{i,k}\)
- 若 \(a_{i,j}=a_{i,k}\),则 \(b_{i,j}=b_{i,k}\)
- 若 \(a_{i,j}<a_{k,j}\),则 \(b_{i,j}<b_{k,j}\)
- 若 \(a_{i,j}=a_{k,j}\),则 \(b_{i,j}=b_{k,j}\)
- \(b\) 中的最大值最小
\(n\times m\leq 10^6\)
建图+并查集
先考虑 \(a\) 中没有重复元素的情况
发现,我们只需要对于每行每列,按值域从小到大,相邻两位置连边,然后 \(b\) 每个位置的权值即为到最小数的距离,在 DAG 上遍历一遍即可
但是若 \(a\) 中有重复元素,直接建图就没有正确性了
\(trick\) :对于同一行同一列的重复元素,建立并查集,进行操作时只用对根节点进行操作
时间复杂度 \(O(nm\log nm)\)
代码
#include <bits/stdc++.h>
using namespace std;
#define get(x, y) ((x - 1) * m + y)
typedef pair <int, int> pii;
const int maxn = 1e6 + 10;
int n, m, tot, a[maxn], f[maxn], par[maxn];
struct node {
int x, y;
bool operator < (const node& o) const {
return a[get(x, y)] < a[get(o.x, o.y)];
}
} dat[maxn];
vector <int> g[maxn];
int find(int x) {
return par[x] == x ? x : par[x] = find(par[x]);
}
void unite(int x, int y) {
par[find(x)] = find(y);
}
int dfs(int u) {
if (~f[u]) return f[u]; f[u] = 0;
for (int v : g[u]) f[u] = max(f[u], dfs(v));
return ++f[u];
}
int main() {
scanf("%d %d", &n, &m), tot = n * m;
for (int i = 1; i <= tot; i++) {
scanf("%d", a + i), par[i] = i;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
dat[j] = node{i, j};
}
sort(dat + 1, dat + m + 1);
for (int j = 1; j < m; j++) {
int u = get(dat[j].x, dat[j].y);
int v = get(dat[j + 1].x, dat[j + 1].y);
if (a[u] == a[v]) unite(u, v);
}
}
for (int j = 1; j <= m; j++) {
for (int i = 1; i <= n; i++) {
dat[i] = node{i, j};
}
sort(dat + 1, dat + n + 1);
for (int i = 1; i < n; i++) {
int u = get(dat[i].x, dat[i].y);
int v = get(dat[i + 1].x, dat[i + 1].y);
if (a[u] == a[v]) unite(u, v);
}
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
dat[j] = node{i, j};
}
sort(dat + 1, dat + m + 1);
for (int j = 1; j < m; j++) {
int u = get(dat[j].x, dat[j].y);
int v = get(dat[j + 1].x, dat[j + 1].y);
if ((u = find(u)) != (v = find(v))) g[v].push_back(u);
}
}
for (int j = 1; j <= m; j++) {
for (int i = 1; i <= n; i++) {
dat[i] = node{i, j};
}
sort(dat + 1, dat + n + 1);
for (int i = 1; i < n; i++) {
int u = get(dat[i].x, dat[i].y);
int v = get(dat[i + 1].x, dat[i + 1].y);
if ((u = find(u)) != (v = find(v))) g[v].push_back(u);
}
}
memset(f, -1, sizeof f);
for (int i = 1; i <= tot; i++) {
if (find(i) == i) dfs(i);
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
printf("%d ", f[find(get(i, j))]);
}
putchar(10);
}
return 0;
}
一种 \(shortest\) 的做法
对于每个元素,按值域从小到大考虑,通过已访问到的行列最大值更新答案
时间复杂度 \(O(nm\log nm)\)
代码
#include <bits/stdc++.h>
using namespace std;
#define get(x, y) ((x - 1) * m + y)
const int maxn = 1e6 + 10;
int n, m, tot, a[maxn], ans[maxn], par[maxn], val[2][maxn];
struct node {
int x, y;
bool operator < (const node& o) const {
return a[get(x, y)] < a[get(o.x, o.y)];
}
} dat[maxn];
int find(int x) {
return par[x] == x ? x : par[x] = find(par[x]);
}
int main() {
scanf("%d %d", &n, &m), tot = n * m;
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
int pos = get(i, j);
scanf("%d", a + pos), dat[pos] = node{i, j}, par[pos] = pos;
}
}
sort(dat + 1, dat + tot + 1);
for (int i = 1; i <= tot; i++) {
int tx = dat[i].x, ty = dat[i].y, pos = get(tx, ty);
int px = find(val[0][tx]), py = find(val[1][ty]), p = find(pos);
ans[p] = max(ans[px] + (a[p] > a[px]), ans[py] + (a[p] > a[py]));
if (a[p] == a[px]) par[px] = p;
if (a[p] == a[py]) par[py] = p;
val[0][tx] = val[1][ty] = p;
}
for (int i = 1; i <= n; i++) {
for (int j = 1; j <= m; j++) {
printf("%d ", ans[find(get(i, j))]);
}
putchar(10);
}
return 0;
}
CF650C Table Compression的更多相关文章
- codeforces Codeforces Round #345 (Div. 1) C. Table Compression 排序+并查集
C. Table Compression Little Petya is now fond of data compression algorithms. He has already studied ...
- Codeforces Round #345 (Div. 1) C. Table Compression dp+并查集
题目链接: http://codeforces.com/problemset/problem/650/C C. Table Compression time limit per test4 secon ...
- Code Forces 650 C Table Compression(并查集)
C. Table Compression time limit per test4 seconds memory limit per test256 megabytes inputstandard i ...
- Codeforces Round #345 (Div. 2) E. Table Compression 并查集
E. Table Compression 题目连接: http://www.codeforces.com/contest/651/problem/E Description Little Petya ...
- Oracle Schema Objects——Tables——Table Compression
Oracle Schema Objects Table Compression 表压缩 The database can use table compression to reduce the amo ...
- codeforces 651E E. Table Compression(贪心+并查集)
题目链接: E. Table Compression time limit per test 4 seconds memory limit per test 256 megabytes input s ...
- MySQL 5.6 Reference Manual-14.7 InnoDB Table Compression
14.7 InnoDB Table Compression 14.7.1 Overview of Table Compression 14.7.2 Enabling Compression for a ...
- Codeforces Round #345 (Div. 2) E. Table Compression 并查集+智商题
E. Table Compression time limit per test 4 seconds memory limit per test 256 megabytes input standar ...
- Codeforces 650C Table Compression
传送门 time limit per test 4 seconds memory limit per test 256 megabytes input standard input output st ...
随机推荐
- JS对全角与半角的验证,相互转化以及介绍
1.什么是全角和半角? 全角:是一种电脑字符,是指一个全角字符占用两个标准字符(或两个半角字符)的位置.全角占两个字节. 汉字字符和规定了全角的英文字符及国标GB2312-80中的图形符号和特殊字符都 ...
- css不受高度限制实现文本超出隐藏并以省略号结束
文本超出省略号显示代码: overflow: hidden; text-overflow:ellipsis; white-space: nowrap;width: 100px; /*宽度做好限制*/ ...
- Linux 安装 Mysql 5.7.23
切换目录 cd /usr 创建目录 mkdir mysql cd mysql 下载 Mysql Yum wget http://repo.mysql.com/mysql57-community-rel ...
- Linux应用和系统库的2种安装方式---源码安装tarball和二进制rpm包
一.应用程序和系统库从哪里来? 两种机制,源码安装和二进制安装. 二.源码安装 tarball 1.核心思想是:利用开源代码,自己编译生成应用程序或者库,要求系统上必须已安装TMG(tar, make ...
- 利用ChromeCROSS可以在chrome浏览器上调试跨域代码
利用ChromeCROSS可以在chrome浏览器上调试跨域代码 1.下载ChromeCROSS文件,可百度下载,或者在我的百度云上下载:链接: https://pan.baidu.com/s/10_ ...
- Thrift的C++服务端(线程池和非阻塞)模式
非阻塞模式 #include "RpcServiceHandler.h" #include <thrift/concurrency/ThreadManager.h> # ...
- codeforces 632C The Smallest String Concatenation
The Smallest String Concatenation 题目链接:http://codeforces.com/problemset/problem/632/C ——每天在线,欢迎留言谈论. ...
- Linux中keepalived+LVS负载均衡的搭建测试
1.1 LVS简介 LVS(Linux Virtual Server),也就是Linux虚拟服务器, 是一个自由软件项目.使用LVS技术要达到的目标是:通过LVS提供的负载均衡技术和Lin ...
- 联想x3650m5服务器安装windows2008R2系统
服务器型号:联想x3650 M5 2U服务器 硬盘:一块300G硬盘 阵列:raid0 系统:windowsserver2008R2系统 安装开始时间:20180930晚上9点 客户手里有window ...
- C语言 排序算法总结
#include<stdio.h> #include<stdlib.h> //作者:凯鲁嘎吉 - 博客园 http://www.cnblogs.com/kailugaji/ # ...