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

来源:Comet OJ - Contest #13

一眼并查集,然后发现这题 tmd 要卡常数的说卧槽...

发现这里又要用并查集跳过访问点,又要用并查集维护联通块,于是开俩并查集分别维护就好了

一开始 XJB 搞了两个并查集建了个完全的连接方式,然后 xjb 写了堆合并,调了一会儿交上去喜见 TLE (自闭现场)

挺好的啊,然后改成动态开点并且访问点跳过的操作也优化了一下,终于爬过去了 ORZ

原 Code

代码挺好打&&极不清爽

//by Judge (zlw ak ioi)
#include<bits/stdc++.h>
#define P pair<int,int>
#define fi first
#define se second
#define Rg register
#define fp(i,a,b) for(Rg int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(Rg int i=(a),I=(b)-1;i>I;--i)
#define ll long long
using namespace std;
const int N=1003,M=N*N;
typedef int ARR[N][N];
typedef int arr[M];
#ifndef Judge
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
#endif
char buf[1<<21],*p1=buf,*p2=buf;
inline int read(){ int x=0,f=1; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;
} inline int read1(){ char c=getchar();
    while(!isdigit(c)) c=getchar(); return c-48;
} char sr[1<<21],z[20];int CCF=-1,Z;
inline void Ot(){fwrite(sr,1,CCF+1,stdout),CCF=-1;}
inline void print(int x,char chr='\n'){
    if(CCF>1<<20)Ot();if(x<0)sr[++CCF]=45,x=-x;
    while(z[++Z]=x%10+48,x/=10);
    while(sr[++CCF]=z[Z],--Z);sr[++CCF]=chr;
} int n,m,q,cnt,ans; ARR id,a; arr fa,f; P po[M];
inline int getf(int x){
    return f[x]^x?f[x]=getf(f[x]):x;
}
inline bool merge(int x,int y){
    return x=getf(x),y=getf(y),x^y?f[y]=x,1:0;
}
inline void newnode(int x,int y){ ++ans;
    if(x>1&&a[x-1][y]&&merge(id[x][y],id[x-1][y])) --ans;
    if(x<n&&a[x+1][y]&&merge(id[x][y],id[x+1][y])) --ans;
    if(y>1&&a[x][y-1]&&merge(id[x][y],id[x][y-1])) --ans;
    if(y<m&&a[x][y+1]&&merge(id[x][y],id[x][y+1])) --ans;
}
inline int find(int x){
    return fa[x]^x?fa[x]=find(fa[x]):x;
}
#define X po[now].fi
#define Y po[now].se
inline void Out(){
    cerr<<ans<<":\n";
    fp(i,1,n){
        fp(j,1,m) cerr<<a[i][j];
        cerr<<"\n";
    } cerr<<"\n\n";
}
int main(){ n=read(),m=read();
    fp(i,1,n) fp(j,1,m+1) ++cnt,
        fa[cnt]=f[cnt]=cnt,po[id[i][j]=cnt]=P(i,j);
    fp(i,1,n) fp(j,1,m) if((a[i][j]=read1()))
        newnode(i,j),fa[id[i][j]]=id[i][j+1];
    q=read(); Rg int x1,x2,y1,y2,now,nxt;
    while(q--){ x1=read(),y1=read(),x2=read(),y2=read();
        fp(i,x1,x2){ now=find(id[i][y1]);
            while(po[now].se<=y2) nxt=find(id[X][Y+1]),
                a[X][Y]=1,newnode(X,Y),fa[now]=nxt,now=nxt;
        } print(ans);
    } return Ot(),0;
}

Code

代码挺好打

//by Judge (zlw ak ioi)
#pragma GCC optimize("Ofast")
#include<bits/stdc++.h>
#define Rg register
#define fp(i,a,b) for(Rg int i=(a),I=(b)+1;i<I;++i)
#define fd(i,a,b) for(Rg int i=(a),I=(b)-1;i>I;--i)
#define ll long long
using namespace std;
const int N=3003,M=N*N;
typedef int ARR[N][N];
typedef int arr[M];
#ifndef Judge
#define getchar() (p1==p2&&(p2=(p1=buf)+fread(buf,1,1<<21,stdin),p1==p2)?EOF:*p1++)
#endif
char buf[1<<21],*p1=buf,*p2=buf;
inline int read(){ int x=0,f=1; char c=getchar();
    for(;!isdigit(c);c=getchar()) if(c=='-') f=-1;
    for(;isdigit(c);c=getchar()) x=x*10+c-'0'; return x*f;
} inline int read1(){ char c=getchar();
    while(!isdigit(c)) c=getchar(); return c-48;
} char sr[1<<21],z[20];int CCF=-1,Z;
inline void Ot(){fwrite(sr,1,CCF+1,stdout),CCF=-1;}
inline void print(int x,char chr='\n'){
    if(CCF>1<<20)Ot();if(x<0)sr[++CCF]=45,x=-x;
    while(z[++Z]=x%10+48,x/=10);
    while(sr[++CCF]=z[Z],--Z);sr[++CCF]=chr;
} int n,m,q,cnt,ans; ARR a,id,fa; arr f;
int getf(int x){
    return f[x]^x?f[x]=getf(f[x]):x;
}
inline void merge(int x,int y){
    x=getf(x),y=getf(y); if(x^y) f[y]=x,--ans;
}
const int h[5]={0,-1,1,0,0},l[5]={0,0,0,-1,1};
inline bool in(int x,int y){
    return x>0&&x<=n&&y>0&&y<=m&&a[x][y];
}
int find(int x,int y){
    return fa[x][y]^y?fa[x][y]=find(x,fa[x][y]):y;
}
inline void newnode(int x,int y){
    a[x][y]=1,++ans,++cnt,f[id[x][y]=cnt]=cnt;
    fa[x][y]=find(x,fa[x][y+1]);
    fp(i,1,4){ Rg int dx=x+h[i],dy=y+l[i];
        if(in(dx,dy)) merge(id[x][y],id[dx][dy]);
    }
}
inline void Out(){ cerr<<"\n\n"<<ans<<":\n";
    fp(i,1,n){ fp(j,1,m) cerr<<a[i][j]; cerr<<"\n"; }
}
int main(){ n=read(),m=read(); fp(i,1,n) fp(j,1,m+1) fa[i][j]=j;
    fp(i,1,n) fp(j,1,m) if((a[i][j]=read1())) newnode(i,j);
    q=read(); Rg int x1,x2,y1,y2,now;
    while(q--){ x1=read(),y1=read(),x2=read(),y2=read();
        fp(i,x1,x2){ now=find(i,fa[i][y1]);
            while(now<=y2) newnode(i,now),now=find(i,fa[i][y1]);
        } print(ans);
    } return Ot(),0;
}

原文地址:https://www.cnblogs.com/Judge/p/11750547.html

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

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

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&l

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

题目描述 ※ 简单版与困难版的唯一区别是 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),表

不是后端也应该知道的「 web 服务、子服务、服务的部署」

web 服务是什么 1. 定义 我们先来看一个很通俗的定义,来自于wiki. Web service 指的是,一个平台通过 web 向其它平台来提供服务. 更专业一点的定义怎么说呢?我们来看一下 W3C 对 web service 的定义. Web service 是一个软件系统,使得不同机器可以在网络间进行互动操作. 2. 要素 想要实现一个平台在网络间调用另一个平台的服务,至少需要明确三点: 如何将平台上的代码作为服务暴露出去供其它平台调用: 使用什么样的网络协议通信: 使用什么样的格式作为

何解決 LinqToExcel 發生「無法載入檔案或組件」問題何解決 LinqToExcel 發生「無法載入檔案或組件」問題

在自己的主機上透過 Visual Studio 2013 與 IISExpress 開發與測試都還正常,但只要部署到測試機或正式機,就是沒辦法順利執行,卡關許久之後找我協助.我發現錯誤訊息確實很「一般」,訊息是:「 無法載入檔案或組件 'LinqToExcel' 或其相依性的其中之一. 試圖載入格式錯誤的程式. 」或是英文版的「 Could not load file or assembly 'LinqToExcel' or one of its dependencies. An attempt

毕业推荐「办理爱尔兰圣尼古拉斯蒙特索瑞学院毕业证」原版一模一样证书

爱尔兰圣尼古拉斯蒙特索瑞学院毕业证[微/Q:9798 3838--WeChat:9798 3838][帖子永久有效,看不到请点击百度快照]联系人Allen[办理毕业证,成绩单,学历认证.文凭.学位证.成绩单等]代办国外(海外)澳洲美国 加拿大 韩国 美国 新西兰 等各大学毕业证,修改成绩单分 数,学历认证,文凭,diploma,degree [删除请点击百度快照]真实认证.海外回囯的同学定制毕业证.真实认证.毕业证.学位证书.使馆公证.囯外真实学位认证.使馆留学回囯人员证明.录取通知书.Offe

SPOJ 16549 - QTREE6 - Query on a tree VI 「一种维护树上颜色连通块的操作」

题意 有操作 $0$ $u$:询问有多少个节点 $v$ 满足路径 $u$ 到 $v$ 上所有节点(包括)都拥有相同的颜色$1$ $u$:翻转 $u$ 的颜色 题解 直接用一个 $LCT$ 去暴力删边连边显然会 $T$ 那么只有两个颜色的话就可以建两棵 $LCT$ ,观察到每次单点修改颜色时其子树所包含连通块在原颜色树上与其父亲所代表连通块断开,所以可以看作断开与父节点的边(实际上是点化边的思想),那么其它常规操作即可 注意要建个虚拟节点作为根节点的父亲 注意 $0$ 操作询问的输出,详细解释有在

csp-s模拟测试94「凉宫春日的犹豫&#183;漫无止境的八月&#183;射手座之日」

凉宫春日的犹豫 题解 第一次秒切题,5分钟切掉 比较$x^y$和$y!$大小 如果$x^y<y!$输出Yes 问题转化为 $\frac{1}{x} *\frac{2}{x}*\frac{3}{x},,,,,*\frac{y}{x}>=1$输出$Yes$ 开双端队列维护,一直保持单调,然后让队首*队尾就行了 代码 #include<bits/stdc++.h> using namespace std; #define ll long long #define A 111111 lon

3年不辭職!記住,在石頭上也要坐3年!(但也要区分5种不值得留的公司,12种留不住人才的公司)

Q:萬一真如你書中所說,碰到很糟糕.只會抱怨公司的Mentor,身為新人應該怎麼處理? A:碰到這種人,可以把他們當作「反面教師」.想想看,他們為何抱怨公司?該怎麼做才能改善?用正面的思考去面對. Q:要是在新人訓練時,發現工作內容跟預期有落差,應該怎麼面對? A:這種情形很常見.新人訓練課程,多少會跟實際工作不同,所以請在被交付的工作上全力以赴! 根據史丹佛大學教授約翰?克倫伯茲(JohnD.Krumboltz)提出的知名理論「計劃性巧合理論」(Planned-HappenstanceTheo

佛佑善人:般若波罗蜜多心经

http://blog.sina.com.cn/s/blog_75b3e1420100v46b.html 观自在菩萨 (般若智慧已经达到自在境界的菩萨) 行深般若波罗蜜多时 (当他修行般若智慧达到波罗蜜多觉悟境界的时候) 照见五蕴皆空 (洞见色.受.想.行.识五蕴乃是人类虚空的妄想) 度一切苦厄 (所以菩萨要为众生解脱一切执着于生死烦恼的苦厄) 舍利子 (智慧第一的舍利子啊) 色不异空 (你所看见的物质世界其实是你的精神世界)空不异色 (你的精神世界也就是你以为的物质世界) 色即是空 (物质世界