CF650C Table Compression

\(\verb|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\) 每个位置的权值即为到最小数的距离,在图上遍历一遍即可

但是若 \(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;
}

原文地址:https://www.cnblogs.com/Juanzhang/p/10424880.html

时间: 2024-10-08 08:10:01

CF650C Table Compression的相关文章

14.7 InnoDB Table Compression

pdf:http://download.csdn.net/detail/paololiu/9576929 14.7 InnoDB Table Compression 14.7.1 Overview of Table Compression 14.7.2 Enabling Compression for a Table 14.7.3 Tuning Compression for InnoDB Tables 14.7.4 Monitoring Compression at Runtime 14.7.

Oracle 表压缩(Table Compression)技术介绍

Oracle 表压缩(Table Compression)介绍 1.官方文档说法: As your database grows in size, consider using table compression. Compression saves disk space, reduces memory use in the database buffer cache, and can significantly speed query execution during reads. Compr

Oracle Schema Objects——Tables——Table Compression

Table Compression 表压缩 The database can use table compression to reduce the amount of storage required for the table. 数据库可以使用表压缩来消除数据块中的重复值. Compression saves disk space, reduces memory use in the database buffer cache, and in some cases speeds query

11G新特性 -- OLTP Table Compression

之前的版本中,只能在批量加载操作时,比如direct load.create table as select 操作,才能压缩数据.在dml操作期间是无法压缩数据的. 在11g中,oracle将表压缩扩展到OLTP负载,比如可以在insert的时候压缩数据. OLTP压缩可以节省50-70%的空间.OLTP压缩不仅不会降低写的性能,还会增加读的性能(直接读取压缩数据). 设置表压缩 普通的压缩表: 1.使用传统方式创建压缩表 SQL> create table ct1(id number) com

Codeforces 650C Table Compression (并查集)

题意:M×N的矩阵 让你保持每行每列的大小对应关系不变,将矩阵重写,重写后的最大值最小. 思路:离散化思想+并查集,详见代码 好题! 1 #include <iostream> 2 #include <string.h> 3 #include <stdio.h> 4 #include <algorithm> 5 #include <cmath> 6 #include <cstdlib> 7 #include <bits/stdc

Data Compression(1)

Supported ü  SQL SERVER 2008,2012 Enterprise, Developer Edition Notice :Backup compression is different of Data Compression. Backup compression was introduced in SQL Server 2008 Enterprise. Beginning in SQL Server 2008 R2, backup compression is suppo

MySQL 5.6 Reference Manual-14.6 InnoDB Table Management

14.6 InnoDB Table Management 14.6.1 Creating InnoDB Tables 14.6.2 Moving or Copying InnoDB Tables to Another Machine 14.6.3 Grouping DML Operations with Transactions 14.6.4 Converting Tables from MyISAM to InnoDB 14.6.5 AUTO_INCREMENT Handling in Inn

Data Block Compression

The database can use table compression to eliminate duplicate values in a data block. This section describes the format of data blocks that use compression. The format of a data block that uses basic and advanced row compression is essentially the sa

数据压缩简要

1. 决定压缩哪些对象 通过sp_estimate_data_compression_savings 评估在ROW和PAGE压缩时分别节省的空间量. 表包含如下数据模式时,会有较好的压缩效果: 数字类型的列和固定长度的字符类型数据,但两者的大多数值都不会用到此类型的所有字节.如INT列的值大多数少于1000. 允许为NULL的列有很多NULL值 列值中有很多一样的值或者相同的前缀. 表包含如下数据模式时,压缩效果较差: 数字类型的列和固定长度的字符类型数据,但是两者的大多数值都会用尽此类型的所有