CF650C Table Compression

给一个 \(n\times m\) 的非负整数矩阵 \(a\),让你求一个 \(n\times m\) 的非负整数矩阵 \(b\),满足以下条件

  1. 若 \(a_{i,j}<a_{i,k}\),则 \(b_{i,j}<b_{i,k}\)
  2. 若 \(a_{i,j}=a_{i,k}\),则 \(b_{i,j}=b_{i,k}\)
  3. 若 \(a_{i,j}<a_{k,j}\),则 \(b_{i,j}<b_{k,j}\)
  4. 若 \(a_{i,j}=a_{k,j}\),则 \(b_{i,j}=b_{k,j}\)
  5. \(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的更多相关文章

  1. 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 ...

  2. Codeforces Round #345 (Div. 1) C. Table Compression dp+并查集

    题目链接: http://codeforces.com/problemset/problem/650/C C. Table Compression time limit per test4 secon ...

  3. Code Forces 650 C Table Compression(并查集)

    C. Table Compression time limit per test4 seconds memory limit per test256 megabytes inputstandard i ...

  4. Codeforces Round #345 (Div. 2) E. Table Compression 并查集

    E. Table Compression 题目连接: http://www.codeforces.com/contest/651/problem/E Description Little Petya ...

  5. Oracle Schema Objects——Tables——Table Compression

    Oracle Schema Objects Table Compression 表压缩 The database can use table compression to reduce the amo ...

  6. codeforces 651E E. Table Compression(贪心+并查集)

    题目链接: E. Table Compression time limit per test 4 seconds memory limit per test 256 megabytes input s ...

  7. 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 ...

  8. 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 ...

  9. Codeforces 650C Table Compression

    传送门 time limit per test 4 seconds memory limit per test 256 megabytes input standard input output st ...

随机推荐

  1. MachineLN博客目录

    MachineLN博客目录 https://blog.csdn.net/u014365862/article/details/78422372 本文为博主原创文章,未经博主允许不得转载.有问题可以加微 ...

  2. springboot Redis 缓存

    1,先整合 redis 和 mybatis 步骤一: springboot 整合 redis 步骤二: springboot 整合 mybatis 2,启动类添加 @EnableCaching 注解, ...

  3. mysql数据库表操作-表的主键索引和普通索引

    数据库索引就象书的目录一样,如果在字段上建立了索引,那么以索引列为查询条件时可以加快查询数据的速度.查询数据库,按主键查询是最快的,每个表只能有一个主键列,但是可以有多个普通索引列,主键列要求列的所有 ...

  4. 使用fiddler抓包手机请求数据

    1.启动Fiddler,打开菜单栏中的 Tools > Fiddler Options,打开“Fiddler Options”对话框. 2.在Fiddler Options”对话框切换到“Con ...

  5. apk公钥私钥用法

    每个密钥都包含两个文件:一个是扩展名为 .x509.pem 的证书,另一个是扩展名为 .pk8 的私钥.私钥需要加以保密,并用于对 apk 包进行签名.密钥本身也可能受密码保护.相比之下,证书只包含公 ...

  6. eclipse配置环境变量 (特别是输入javac无显示问题)

    下载JDK:http://www.oracle.com/technetwork/java/javase/downloads/index.html 最近win10恢复了一下系统,重新给eclipse配一 ...

  7. 【转】JSF中的三大核心组件 UI标签的详细介绍和使用举例

    JSF提供了大量的UI标签来简化创建视图.这些UI标签类似于ASP.NET中的服务器组件.使用这些标签,可以通过其value,binding,action,actionListener等属性直接绑定到 ...

  8. Android内嵌PDF预览

    一.在对应模块的build.gradle文件中加入依赖 dependencies { implementation 'com.github.barteksc:android-pdf-viewer:3. ...

  9. SudokuGame 记软工第二次作业

    整体概况 1.描述编写整体程序正确过程(含关键代码) 2.整体心路历程及新知分析 3.效能分析.构建之法及整体耗时时间表 4.一些心得体会 GitHub 链接如下: 1.[基础作业BIN文件(最新版) ...

  10. 阿里八八Beta冲刺博客集合贴

    Scrum 阿里八八β阶段Scrum(1/5) 阿里八八β阶段Scrum(2/5) 阿里八八β阶段Scrum(3/5) 阿里八八β阶段Scrum(4/5) 阿里八八β阶段Scrum(5/5) 总结 阿 ...