• [CF1303F] Number of Components


    有一个 (n imes m) 矩阵,初态下全是 (0)

    如果两个相邻元素(四连通)相等,我们就说它们是连通的,且这种关系可以传递。

    (q) 次操作,每次指定一个位置 ((x_i,y_i)) 把它替换为 (c_i)

    每次操作后求这个矩阵有多少个连通块。

    (q leq 2 imes 10^6), (n,m leq 300)

    Solution

    带删除的并查集问题可以离线,所以正着倒着各做一次,然后将答案做差就可以了

    考虑正着做的过程,刚开始就是一块 (0) 的板板

    每次我们创建一个新节点,然后试图将它与周围的节点合并,设合并的次数为 (t),那么这一次对答案的贡献(即这次操作新增了多少个连通块)就是 (1-t)

    反向操作时同理,贡献带个负号就可以了

    最后输出答案的时候,把贡献数组求个前缀和即可

    #include <bits/stdc++.h>
    using namespace std;
    
    const int N = 305, M = 2000005;
    int a[N][N],n,m,q,ind,num,f[M*2],ans[M],id[N][N];
    
    struct query {
        int x,y,b,c;
    } s[M];
    
    int find(int x) {return (x==f[x])?x:f[x]=find(f[x]);}
    void merge(int x,int y) {if((x=find(x))-(y=find(y))) f[x]=y,--num;}
    
    void solve(int x,int y) {
        if(a[x][y]==a[x-1][y]) merge(id[x][y],id[x-1][y]);
        if(a[x][y]==a[x+1][y]) merge(id[x][y],id[x+1][y]);
        if(a[x][y]==a[x][y-1]) merge(id[x][y],id[x][y-1]);
        if(a[x][y]==a[x][y+1]) merge(id[x][y],id[x][y+1]);
    }
    
    signed main() {
        scanf("%d%d%d",&n,&m,&q);
        for(int i=1;i<=q;i++) {
            int x,y,c;
            scanf("%d%d%d",&x,&y,&c);
            s[i]={x,y,a[x][y],c};
            a[x][y]=c;
        }
        memset(a,0xff,sizeof a);
        for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) a[i][j]=0;
        for(int i=1;i<=q;i++) {
            if(s[i].b!=s[i].c) {
                int x=s[i].x,y=s[i].y,b=s[i].b,c=s[i].c;
                num=1;
                a[x][y]=c;
                id[x][y]=++ind;
                f[ind]=ind;
                solve(x,y);
                ans[i]+=num;
            }
        }
        ind=0;
        memset(f,0,sizeof f);
        for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) {
            id[i][j]=++ind;
            f[ind]=ind;
        }
        for(int i=1;i<=n;i++) for(int j=1;j<=m;j++) solve(i,j);
        for(int i=q;i>=1;--i) {
            if(s[i].b!=s[i].c) {
                int x=s[i].x,y=s[i].y,b=s[i].c,c=s[i].b;
                num=1;
                a[x][y]=c;
                id[x][y]=++ind;
                f[ind]=ind;
                solve(x,y);
                ans[i]-=num;
            }
        }
        ans[0]=1;
        for(int i=1;i<=q;i++) ans[i]+=ans[i-1];
        for(int i=1;i<=q;i++) printf("%d
    ",ans[i]);
    }
    
    
  • 相关阅读:
    [ ERROR ] Error in test library 'pymysql': Creating keyword 'Connect' failed: Keyword with same name defined multiple times.
    【robotframework】pycharm+robotframe(转)
    Django 配置mysql遇到问题(一)
    Django 初始化数据库遇到问题(python manage.py migrate)
    连接mysql报"ERROR 1130: Host xxx.xxx.xxx.xxx is not allowed to connect to this MySQL server"
    性能测试-MySQL性能查看(转)
    APP安全测试
    在线java堆栈分析工具
    性能-如何根据线程和进程找到性能瓶颈或者问题点
    Jmeter CSV参数带汉字处理
  • 原文地址:https://www.cnblogs.com/mollnn/p/12348558.html
Copyright © 2020-2023  润新知