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 ...
随机推荐
- CentOS7 离线安装MySQL
1.删除原有的mariadb 不然安装报错 rpm -qa|grep mariadb rpm -e --nodeps mariadb-libs 2. 下载RPM安装包 在https://dev.mys ...
- 照葫芦画瓢系列之Java --- Maven的配置
一.Maven仓库分类 Maven中,仓库只分为两类:本地仓库和远程仓库.当Maven根据坐标寻找构件的时候,它首先去查看本地仓库,如果本地仓库有此构件,则直接使用,如果本地仓库不存在此构件,或者需要 ...
- 矢量图面层和线层相交得到相交后的线层文件(gis相交)
目的:将arcgis里的面层和线层相交(重叠)部分的线单独生成一个shp文件,用于道路路网密度计算等. 注意:进行相交运算后生成的是线要素文件,相当于把面线相交部分的线单独拿了出来. 操作例子:将图示 ...
- [Android][Framework] 添加系统服务
新博客地址 http://wossoneri.github.io/2018/09/15/[Android][Framework]create-system-service/ 做系统开发,有时候需要自己 ...
- python爬虫从入门到放弃(九)之 Requests+正则表达式爬取猫眼电影TOP100
import requests from requests.exceptions import RequestException import re import json from multipro ...
- 【redis专题(9)】事务
Redis支持简单的事务,所谓简单是因为其不支持回滚(回滚是用队列模仿的),与mysql有以下区别 rollback与discard的区别: 如果已经成功执行了2条语句, 第3条语句出错 Rollba ...
- mysql 最左匹配 联合索引
mysql建立多列索引(联合索引)有最左前缀的原则,即最左优先,如: 如果有一个2列的索引(col1,col2),则已经对(col1).(col1,col2)上建立了索引:如果有一个3列索引(col1 ...
- Mysql内置优化工具show profiles
一.概述: Mysql的explain工具目前还没有Oracle的explain plan工具那么强大,但是结合show profiles工具可以实现相似的效果.show profiles语句用于在当 ...
- Windows Server 2016-管理Active Directory复制任务
Repadmin.exe可帮助管理员诊断运行Microsoft Windows操作系统的域控制器之间的Active Directory复制问题. Repadmin.exe内置于Windows Serv ...
- 为爱好舞蹈的人们做的软件,细究数据结构,操作系统,磁盘原理,用java/c/c++写一个开源 MP3助手
1.可以给歌曲间插播空白音乐 2.拖拽式调整 3.先排序,后一键写入顺序文件. 国外的开源软件 MP3 播放排序 http://www.murraymoffatt.com/software-prob ...