Comet OJ - Contest #13 「佛御石之钵 -不碎的意志-」(困难版) 并查集

题意

给一个$ n \times m$ 的网格,每个格子里有一个数字,非 \(0\) 即 \(1\),行从上往下依次编号为 \(1, 2, \cdots, n\),列从左往右依次编号为 \(1, 2, \cdots, m\)。

给 \(q\) 次操作,每次给定一个以 \((x_1,y_1)\) 为左上角,\((x_2,y_2)\) 为右下角的矩形内所有格子里的数字都变成 \(1\)。问每次操作之后,所有数字为 \(1\)的格子构成的四连通块的个数。

\(1<=n,m<=1000\)

\(1<=q<=30000\)

分析

搬运官方题解..

Code

#include<bits/stdc++.h>
#define fi first
#define se second
#define lson l,mid,p<<1
#define rson mid+1,r,p<<1|1
#define pb push_back
#define ll long long
using namespace std;
const int inf=1e9;
const int mod=1e9+7;
const int maxn=1e6+10;
int n,m,q;
char s[1010][1010];
int id[1010][1010],f[maxn];
int xx[]={0,0,1,-1};
int yy[]={1,-1,0,0};
int g[1010][1010];
int ans,tot;
int find(int k){
    if(k==f[k]) return k;
    return f[k]=find(f[k]);
}
int ff(int x,int k){
    if(k==g[x][k]) return k;
    return g[x][k]=ff(x,g[x][k]);
}
void dfs(int x,int y){
    ++ans,id[x][y]=++tot;f[tot]=tot;
    int rx=ff(x,y),ry=ff(x,y+1);
    if(rx!=ry) g[x][rx]=ry;
    for(int i=0;i<4;i++){
        int dx=x+xx[i];
        int dy=y+yy[i];
        if(dx<1||dx>n||dy<1||dy>m||!id[dx][dy]) continue;
        int rx=find(id[x][y]),ry=find(id[dx][dy]);
        if(rx!=ry) f[rx]=ry,--ans;
    }
}
int main(){
    //ios::sync_with_stdio(false);
    //freopen("in","r",stdin);
    scanf("%d%d",&n,&m);
    int tot=0;
    for(int i=1;i<=n;i++)
    for(int j=1;j<=m+1;j++) g[i][j]=j;
    for(int i=1;i<=n;i++){
        scanf("%s",s[i]+1);
        for(int j=1;j<=m;j++) if(s[i][j]=='1'){
             dfs(i,j);
        }
    }
    scanf("%d",&q);
    while(q--){
        int x1,y1,x2,y2;
        scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
        for(int i=x1;i<=x2;i++){
            for(int j=ff(i,y1);j<=y2;j=ff(i,y1)){
                dfs(i,j);
            }
        }
        printf("%d\n",ans);
    }
    return 0;
}

原文地址:https://www.cnblogs.com/xyq0220/p/11741455.html

时间: 2024-11-08 08:32:27

Comet OJ - Contest #13 「佛御石之钵 -不碎的意志-」(困难版) 并查集的相关文章

「佛御石之钵 -不碎的意志-」(困难版)

题目描述 ※ 简单版与困难版的唯一区别是 n,m,q 的数据范围 给一个n×m 的网格,每个格子里有一个数字,非 00 即 11,行从上往下依次编号为 1, 2?,n,列从左往右依次编号为 1,2,?,m. 给 qq 次操作,每次给定一个以(x1?,y1?) 为左上角,(x2?,y2?) 为右下角的矩形内所有格子里的数字都变成 1.问每次操作之后,所有数字为 1 的格子构成的四连通块的个数. 若不懂四连通块的定义可见最底下的提示. 输入描述 输入第一行两个整数 n,m(1≤n,m≤1000),表

「佛御石之钵 -不碎的意志-」(hard)

来源:Comet OJ - Contest #13 一眼并查集,然后发现这题 tmd 要卡常数的说卧槽... 发现这里又要用并查集跳过访问点,又要用并查集维护联通块,于是开俩并查集分别维护就好了 一开始 XJB 搞了两个并查集建了个完全的连接方式,然后 xjb 写了堆合并,调了一会儿交上去喜见 TLE (自闭现场) 挺好的啊,然后改成动态开点并且访问点跳过的操作也优化了一下,终于爬过去了 ORZ 原 Code 代码挺好打&&极不清爽 //by Judge (zlw ak ioi) #inc

Comet OJ - Contest #13

第一次打这种比赛.还是有不少问题的,以后改吧. A题WA了两次罚了不少时. C写到一半发现只能过1,就先弃了. D一眼没看出来.第二眼看出来就是一个类似于复数的快速幂. 然后B切了. 最后切C,图中还重构了一次.还TLE了3发.浪费了大量时间. Tips: 1.A题FB基本上拿不到的,好好写1A就没事了. 2.先看一遍,大码题和数据结构放后面. 3.先开数论,就TM死刚数论.(这次要是切A之后直接刚D就有FB了) 4.别急,奖励拿不拿就那样吧. 下面是solution: A 签到题. #incl

Comet OJ - Contest #13 补题题解

A.险恶的迷宫 题意:在二维平面坐标内,给出一个圆心坐标 (a,b),以及圆的半径 r , 再给出 n 个点的坐标 (x_i,y_i),  求有多少点在圆内. 数据范围:0  <  n  <= 1e5,      0< r , x , y  <=1e9 思路:对于判断距离根据勾股定理: sqrt((x1-x2)*(x1-x2)+(y1-y2)*(y1-y2)) <= r ,即在圆的范围内.由于此题数据较大,sqrt可能导致精度损失,所以直接开long long 进行平方比较

符文能量(Comet OJ - Contest #8)

给Comet OJ打个小广告,挺好用的,比较简洁,给人感觉很好用 Contest #8是我打的第一场本oj比赛,很遗憾A了前两道傻逼题就没思路了,然后就不打算打了....... https://www.cometoj.com/contest/58/problem/C?problem_id=2760 怎么做啊完全不会啊我那么菜,虽然看到是dp但嫌太麻烦就放弃了: 靠后仔细想了想原来这道题很简单: 结构体node e[];储存ai,bi值(当然你用数组我也不拦着),因为合并的方式很特殊,可以不管合并

Comet OJ - Contest #5

Comet OJ - Contest #5 总有一天,我会拿掉给\(dyj\)的小裙子的. A 显然 \(ans = min(cnt_1/3,cnt_4/2,cnt5)\) B 我们可以感性理解一下,最大的满足条件的\(x\)不会太大 因为当\(x\)越来越大时\(f(x)\)的增长速度比\(x\)的增长速度慢得多 其实可以证明,最大的满足的\(x\)不会超过\(100\) 因为没有任何一个三位数的各位之和大于等于\(50\) 所以我们就直接预处理\(1-99\)所有的合法的 暴力枚举即可 其实

Comet OJ - Contest #10 B

Comet OJ - Contest #10 B 沉鱼落雁 思维题 题意 : 每个数字最多重复出现三次,有n给数字,让你尽可能的使得相同数字之间的最小距离尽可能大 思路 :分三种情况套路 设 a b c 分别代表出现 一次, 两次, 三次 数字的个数 所有元素至多出现一次,答案为 n,题目规定 所有元素至多出现两次, 例如 1 1 2,可以排列成 1 2 1,所以,答案为 1 例如 1 1 2 2 3,可以排列成 1 2 3 1 2,所有 答案为 2 思考后得出,应该尽可能的把 b 个出现两次的

Comet OJ - Contest #15

https://cometoj.com/contest/79/problem/D?problem_id=4219 题目描述 ※ 简单版与困难版的唯一区别是粗体字部份和 $v$ 的数据范围. 在双 11 时,心慧精品店有个特别的折价活动如下: 首先,我们定义一个正整数为"好的"当且仅当此数仅由数字 1 构成,举例来说 1, 11, 111, 11111 都是「好的」,但 10.123.321 都是「不好的」. 接着,若一个商品原价为 x,若顾客能把 x 表示为 k 个「好的」数字,那么此

Comet OJ - Contest #15题解

A 双十一特惠 (简单版) n  <=  1e19,   1e9 > 1(8) https://www.cometoj.com/contest/79/problem/A?problem_id=4198 #include<bits/stdc++.h> using namespace std; int main(){ int t; cin >> t; while(t--) { int cnt1 = 0; int n;cin >> n; int pr[] = {1