zoukankan      html  css  js  c++  java
  • 2020.10.6 提高组模拟

    2020.10.6 提高组模拟

    6815. 【2020.10.06提高组模拟】树的重心


    Description

    给定 (n imes m) 的矩阵,((i, j)) 的颜色为 (s_{i,j})
    q 次操作,每次将 ((1, 1)) 所在的连通块颜色替换,求每次替换后连通块的大小。
    连通块:若 ((x, y))((x', y;)) 存在公共边且颜色相同则在同一连通块内。

    Data Constraint

    (1 leq n, m leq 1000)(1 leq 颜色种类数 leq 10^6),操作数小于等于 (2 imes 10^5)

    Solution

    只需要维护与 ((1, 1)) 所在连通块相连的点即可,用一个队列维护每种颜色的点,
    每次操作将与替换颜色相同的点所在的连通块加入答案,
    并把连通块周围未加入队列的点加入队列。

    提前将处理出连通块也许可以简化操作。

    Code

    #include <cstdio>
    #include <cstring>
    #include <algorithm>
    #include <bitset>
    
    using namespace std;
    
    #define N 1001
    #define M 1000001
    
    #define fo(i, x, y) for(int i = x; i <= y; i ++)
    #define Fo(i, x, q) for(int i = x; i; i = q[i].next)
    
    struct NEXT_P { int x, next; } p1[M + 1], p2[M << 2];
    
    struct Arr { int x, y, f, siz; } fa[M << 1];
    
    int h1[M << 1], h2[M + 1], c[N + 1][N + 1], a[N + 1][N + 1];
    
    bitset <M << 1> used, vis;
    
    int n, m, q, k, cnt1 = 0, cnt2 = 0, tot = 0, ans = 0;
    
    void read(int &x) {
        char ch = getchar(); x = 0;
        while (ch < '0' || ch > '9') ch = getchar();
        while (ch >= '0' && ch <= '9') x = (x << 1) + (x << 3) + ch - 48, ch = getchar();
    }
    
    int Getfa(int x) { return x == fa[x].f ? x : fa[x].f = Getfa(fa[x].f); }
    
    void Merge(int u, int v) {
        int x = Getfa(u), y = Getfa(v);
        if (x == y) return;
        fa[y].siz += fa[x].siz;
        fa[x].f = fa[y].f;
    }
    
    void Add2(int u, int v) { p2[ ++ cnt2 ] = (NEXT_P) { v, h2[u] }, h2[u] = cnt2; }
    void Link(int u, int v) { Add2(u, v), Add2(v, u); }
    
    void Add1(int col, int v) { p1[ ++ cnt1 ] = (NEXT_P) { v, h1[col] }, h1[col] = cnt1; }
    
    int test1 = 0, test2 = 0;
    
    void Solve(int col) {
        Fo(i, h1[col], p1) if (! used[p1[i].x]) {
            used[p1[i].x] = 1, h1[col] = p1[i].next;
            ans += fa[p1[i].x].siz;
    
            Fo(j, h2[p1[i].x], p2) if (! vis[p2[j].x])
                Add1(c[fa[p2[j].x].x][fa[p2[j].x].y], p2[j].x), vis[p2[j].x] = 1;
        }
    }
    
    int main() {
        freopen("color.in", "r", stdin);
        freopen("color.out", "w", stdout);
    
        read(n), read(m), read(q), read(k);
        fo(i, 1, n) fo(j, 1, m) read(c[i][j]);
    
        fo(i, 1, n) fo(j, 1, m) fa[ a[i][j] = ++ tot ] = (Arr) { i, j, tot, 1 };
        fo(i, 1, n) fo(j, 1, m) {
            if (i > 1 && c[i - 1][j] == c[i][j])
                Merge(a[i][j], a[i - 1][j]);
            if (j > 1 && c[i][j - 1] == c[i][j])
                Merge(a[i][j], a[i][j - 1]);
        }
        fo(i, 1, n) fo(j, 1, m) {
            if (i > 1 && c[i - 1][j] != c[i][j])
                Link(Getfa(a[i - 1][j]), Getfa(a[i][j]));
            if (j > 1 && c[i][j - 1] != c[i][j])
                Link(Getfa(a[i][j - 1]), Getfa(a[i][j]));
        }
        used.reset(), vis.reset();
        Add1(c[1][1], Getfa(a[1][1]));
        vis[Getfa(a[1][1])] = 1;
        Solve(c[1][1]);
        int x;
        fo(OPT, 1, q) {
            read(x);
            Solve(x);
            printf("%d
    ", ans);
        }
    
        return 0;
    }
    

    6815.【2020.10.06提高组模拟】树的重心


    Description & Solution

    6816. 【2020.10.06提高组模拟】随机的排列


    暂时还不会...

  • 相关阅读:
    VMware 虚拟机NAT模式如何设置网络连接,从头到尾全过程~!!
    mysql数据库中的索引介绍与优化(转)
    AWS磁盘容量问题
    Shell实现强制释放内存
    Tomcat #无法启动8005端口
    100个命令Linux常用命令大全
    Keepalived+Nginx实现高可用负载均衡集群
    python 备份压缩传输
    Python 数据库备份脚本
    shell自动化巡检
  • 原文地址:https://www.cnblogs.com/zhouzj2004/p/13788033.html
Copyright © 2011-2022 走看看