| 比赛 |
2026.9.12 |
评测结果 |
AAAAAAAAAA |
| 题目名称 |
彩色卡牌 |
最终得分 |
100 |
| 用户昵称 |
RpUtl |
运行时间 |
10.288 s |
| 代码语言 |
C++ |
内存使用 |
107.23 MiB |
| 提交时间 |
2026-09-12 12:28:44 |
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
const int N = 5e5 + 10;
int r, c, q, f[N], id, rt, n, st[N][21], cnt, tot;
int rk[N], dfn[N], de[N], sz[N], col[N], val[N];
int a[505][505], fx[] = {1, 0}, fy[] = {0, 1};
struct edge { int u, v, w; } e[N];
set<int> stc[N];
vector<int> G[N];
int ID(int x, int y) {
return (x - 1) * c + y;
}
struct BIT {
int c[N];
void add(int x, int y) {
// cout << rk[x] << " add " << y << " " << id << '\n';
for (; x <= id; x += (x & -x)) c[x] += y;
return;
}
int ask(int x, int y = 0) {
for (; x > 0; x -= (x & -x)) y += c[x];
return y;
}
int qry(int l, int r) {
return ask(r) - ask(l - 1);
}
} T;
void add(int x, int y) {
G[x].push_back(y);
}
bool cmp(edge a, edge b) {
return a.w < b.w;
}
void dfs(int x, int fa) {
st[x][0] = fa, rk[dfn[x] = ++cnt] = x, sz[x] = 1, de[x] = de[fa] + 1;
for (int i = 1; i <= 20; i++) st[x][i] = st[st[x][i - 1]][i - 1];
for (auto y : G[x]) dfs(y, x), sz[x] += sz[y];
}
int LCA(int a, int b) {
if (de[a] < de[b]) swap(a, b);
for (int i = 20; i >= 0; i--) if (de[st[a][i]] >= de[b]) a = st[a][i];
if (a == b) return a;
for (int i = 20; i >= 0; i--) if (st[a][i] != st[b][i]) a = st[a][i], b = st[b][i];
return st[a][0];
}
void ins(int x) {
T.add(dfn[x], 1); int pre = 0, nxt = 0, z;
auto it = stc[col[x]].upper_bound(dfn[x]);
if (it != stc[col[x]].end()) {
nxt = rk[*it], z = LCA(x, nxt);
T.add(dfn[z], -1);
}
if (it != stc[col[x]].begin()) {
--it; pre = rk[*it], z = LCA(x, pre);
T.add(dfn[z], -1);
}
if (nxt && pre) {
z = LCA(nxt, pre);
T.add(dfn[z], 1);
}
stc[col[x]].insert(dfn[x]);
return;
}
void del(int x) {
T.add(dfn[x], -1); int nxt = 0, pre = 0, z;
stc[col[x]].erase(dfn[x]);
auto it = stc[col[x]].upper_bound(dfn[x]);
if (it != stc[col[x]].end()) {
nxt = rk[*it], z = LCA(x, nxt);
T.add(dfn[z], 1);
}
if (it != stc[col[x]].begin()) {
--it; pre = rk[*it], z = LCA(x, pre);
T.add(dfn[z], 1);
}
if (nxt && pre) {
z = LCA(nxt, pre);
T.add(dfn[z], -1);
}
return;
}
int ask(int p, int v) {
if (val[p] > v) return 0;
for (int i = 20; i >= 0; i--) {
if (val[st[p][i]] <= v) p = st[p][i];
}
return T.qry(dfn[p], dfn[p] + sz[p] - 1);
}
int found(int x) {
return f[x] == x ? x : f[x] = found(f[x]);
}
int main() {
freopen("card.in", "r", stdin);
freopen("card.out", "w", stdout);
ios::sync_with_stdio(0);
cin.tie(0), cout.tie(0);
cin >> r >> c >> q;
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= c; j++) {
cin >> a[i][j];
val[ID(i, j)] = a[i][j];
}
}
for (int i = 1; i <= r; i++) {
for (int j = 1, b; j <= c; j++) {
cin >> b;
col[ID(i, j)] = b;
}
}
n = r * c;
for (int i = 1; i <= r; i++) {
for (int j = 1; j <= c; j++) {
for (int k = 0; k < 2; k++) {
int x = i + fx[k], y = j + fy[k];
if (x < 1 || x > r || y < 1 || y > c) continue;
e[++tot] = {ID(i, j), ID(x, y), max(a[i][j], a[x][y])};
}
}
}
sort(e + 1, e + 1 + tot, cmp);
id = n;
for (int i = 1; i <= n; i++) f[i] = i;
for (int i = 1; i <= tot; i++) {
int u = found(e[i].u);
int v = found(e[i].v);
if (u == v) continue;
++id; f[id] = id, f[u] = id, f[v] = id;
add(id, u), add(id, v), val[id] = e[i].w;
}
rt = id, val[0] = 1e9, dfs(rt, 0);
for (int i = 1; i <= n; i++) ins(i);
int o, x, y, c;
for (int i = 1; i <= q; i++) {
cin >> o >> x >> y >> c;
if (o == 1) {
int u = ID(x, y);
del(u), col[u] = c, ins(u);
} else {
cout << ask(ID(x, y), c) << '\n';
}
}
return 0;
}