比赛 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;
}