#分块,可撤销并查集#洛谷 5443 [APIO2019]桥梁
分析
最直接的做法就是在线一边修改边权,询问直接全部重排,
然后用可撤销并查集维护连通块大小,这样时间复杂度为 \(O(qm)\)
同样尽量让大部分的边不需要修改边权,那么每 \(B\) 个操作整体进行一次,
那么最多只有 \(B\) 条边会修改,剩下的边直接用双指针加入并查集。
这 \(B\) 条边直接每次询问修改边权,然后排序加入并查集,询问完与剩下的边归并排序
那么时间复杂度为 \(O(qB\log n+\frac{m^2}{B}\log n)\),实际上 \(B\) 取 \(\sqrt{m\log n}\) 跑得比较快。
注意可撤销并查集不能通过siz的大小合并,只是为了方便,但可能会被卡。
代码
#include <cstdio>
#include <cctype>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=100011; struct node{int x,y,w;}e[N]; struct rec{int x,y,rk;}q[N],a[N];
int n,m,Q,bl,f[N],rk[N],siz[N],ans[N],Fa[N],tod,Fb[N],v[N],Rk[N],RK[N],rK[N];
int iut(){
int ans=0; char c=getchar();
while (!isdigit(c)) c=getchar();
while (isdigit(c)) ans=ans*10+c-48,c=getchar();
return ans;
}
void print(int ans){
if (ans>9) print(ans/10);
putchar(ans%10+48);
}
bool cmp0(int x,int y){return e[x].w>e[y].w;}
bool cmp1(int x,int y){return q[x].y>q[y].y;}
int getf(int u){return f[u]==u?u:getf(f[u]);}
void Merge(int x,int y){
int fa=getf(x),fb=getf(y);
if (siz[fa]>siz[fb]) swap(fa,fb);
if (fa==fb) return;
f[fa]=fb,siz[fb]+=siz[fa],Fa[++tod]=fa,Fb[tod]=fb;
}
int main(){
n=iut(),m=iut();
for (int i=1;i<=m;++i) e[i]=(node){iut(),iut(),iut()};
for (int i=1;i<=n;++i) f[i]=i,siz[i]=1;
for (int i=1;i<=m;++i) rk[i]=i;
Q=iut(),bl=sqrt(m*log(n)),sort(rk+1,rk+1+m,cmp0);
for (int l=1,r;l<=Q;l+=bl){
if (l+bl>Q) r=Q; else r=l+bl-1;
int tot=0,cnt=0,TOT=0,ToT=0;
for (int i=l;i<=r;++i){
int opt=iut(),x=iut(),y=iut();
if (opt==1) ++tot,a[tot]=(rec){x,y,tot},v[x]=l;
else q[++cnt]=(rec){x,y,tot},Rk[cnt]=cnt;
}
if (!cnt) continue;
for (int i=1;i<=m;++i) if (v[i]==l) rK[++TOT]=i;
sort(Rk+1,Rk+1+cnt,cmp1);
for (int i=1,j=1;i<=cnt;++i){
for (;j<=m&&e[rk[j]].w>=q[Rk[i]].y;++j)
if (v[rk[j]]!=l) Merge(e[rk[j]].x,e[rk[j]].y);
for (int k=1;k<=q[Rk[i]].rk;++k) swap(e[a[k].x].w,a[k].y);
int Tod=tod;
for (int k=1;k<=TOT;++k)
if (e[rK[k]].w>=q[Rk[i]].y)
Merge(e[rK[k]].x,e[rK[k]].y);
ans[Rk[i]]=siz[getf(q[Rk[i]].x)];
for (;tod>Tod;--tod) siz[Fb[tod]]-=siz[Fa[tod]],f[Fa[tod]]=Fa[tod];
for (int k=q[Rk[i]].rk;k;--k) swap(e[a[k].x].w,a[k].y);
}
for (;tod;--tod) siz[Fb[tod]]-=siz[Fa[tod]],f[Fa[tod]]=Fa[tod];
for (int k=1;k<=tot;++k) swap(e[a[k].x].w,a[k].y);
sort(rK+1,rK+1+TOT,cmp0);
int I=1,J=1;
while (I<=TOT){
while (J<=m&&v[rk[J]]==l) ++J;
if (J<=m&&e[rk[J]].w>=e[rK[I]].w) RK[++ToT]=rk[J++];
else RK[++ToT]=rK[I++];
}
for (;J<=m;++J) if (v[rk[J]]!=l) RK[++ToT]=rk[J];
for (int i=1;i<=ToT;++i) rk[i]=RK[i];
for (int i=1;i<=cnt;++i) print(ans[i]),putchar(10);
}
return 0;
}
#分块,可撤销并查集#洛谷 5443 [APIO2019]桥梁的更多相关文章
- [BZOJ4537][Hnoi2016]最小公倍数 奇怪的分块+可撤销并查集
4537: [Hnoi2016]最小公倍数 Time Limit: 40 Sec Memory Limit: 512 MBSubmit: 1474 Solved: 521[Submit][Stat ...
- 【简单数据结构】并查集--洛谷 P1111
题目背景 AA地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车.政府派人修复这些公路. 题目描述 给出A地区的村庄数NN,和公路数MM,公路是双向的.并告诉你每条公路的连着哪两个村庄,并告诉你 ...
- bzoj2049 线段树 + 可撤销并查集
https://www.lydsy.com/JudgeOnline/problem.php?id=2049 线段树真神奇 题意:给出一波操作,拆边加边以及询问两点是否联通. 听说常规方法是在线LCT, ...
- CodeForces892E 可撤销并查集/最小生成树
http://codeforces.com/problemset/problem/892/E 题意:给出一个 n 个点 m 条边的无向图,每条边有边权,共 Q 次询问,每次给出 ki 条边,问这些边 ...
- BZOJ4358: permu(带撤销并查集 不删除莫队)
题意 题目链接 Sol 感觉自己已经老的爬不动了.. 想了一会儿,大概用个不删除莫队+带撤销并查集就能搞了吧,\(n \sqrt{n} logn\)应该卡的过去 不过不删除莫队咋写来着?....跑去学 ...
- 【离线 撤销并查集 线段树分治】bzoj1018: [SHOI2008]堵塞的交通traffic
本题可化成更一般的问题:离线动态图询问连通性 当然可以利用它的特殊性质,采用在线线段树维护一些标记的方法 Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常 ...
- codeforces 892E(离散化+可撤销并查集)
题意 给出一个n个点m条边的无向联通图(n,m<=5e5),有q(q<=5e5)个询问 每个询问询问一个边集{Ei},回答这些边能否在同一个最小生成树中 分析 要知道一个性质,就是权值不同 ...
- 【Codeforces576E_CF576E】Painting Edges(可撤销并查集+线段树分治)
题目 CF576E 分析: 从前天早上肝到明天早上qwq其实颓了一上午MC ,自己瞎yy然后1A,写篇博客庆祝一下. 首先做这题之前推荐一道很相似的题:[BZOJ4025]二分图(可撤销并查集+线段树 ...
- 【BZOJ4025】二分图(可撤销并查集+线段树分治)
题目: BZOJ4025 分析: 定理:一个图是二分图的充要条件是不存在奇环. 先考虑一个弱化的问题:保证所有边出现的时间段不会交叉,只会包含或相离. 还是不会?再考虑一个更弱化的问题:边只会出现不会 ...
- 算法笔记--可撤销并查集 && 可持久化并查集
可撤销并查集模板: struct UFS { stack<pair<int*, int>> stk; int fa[N], rnk[N]; inline void init(i ...
随机推荐
- win32 - 内存映射(CreateFileMapping)
目标:创建一个app,使用CreateToolhelp32Snapshot扫描所有的进程,并将进程的pid和exe名字映射到内存中,再在另一个app中使用OpenFileMapping打开该映射读取相 ...
- [Android逆向]Exposed 破解 jwxdxnx02.apk
使用exposed 遇到了一些坑,这里记录一下 源码: package com.example.exposedlesson01; import de.robv.android.xposed.IXpos ...
- isort包
记录 为什么会使用到这个包,原因是之前在本地开发的时候,导包的时候可能由于不规范,其实你自己看着挺规范的,但是呢后续组长进行打包的时候,代码出现了不规范的情况,导致打包失败.原因就是导包不规范造成的. ...
- celery正常启动后能接收任务但不执行(已解决)
错误截图:celery接收到任务却不执行(多出在windows系统中) 解决方法1 添加–pool=solo参数 celery -A celery_tasks.main worker --pool=s ...
- 【Azure 应用服务】App Service下部署的应用报错 Out of Memory
问题描述 应用部署到App Service后,遇见了Out of Memory的错误. 报错信息:GetData Error:, Exception of type 'System.OutOfMem ...
- Java //手动输入3个数,并从小到大排序
1 //手动输入3个数,并从小到大排序 2 //import java.util.Sanner; 3 4 System.out.println("请输入第一个数:"); 5 Sca ...
- Educational Codeforces Round 143 (Rated for Div. 2)C. Tea Tasting(前缀和+二分、贡献枚举)
C. Tea Tasting 思路 这里枚举有三种思路 然后经过考虑3是最可行的,然后接着考虑如何计算贡献 这里在实现的时候用了一个差分数组,因为我们需要记录第i个茶师它喝了多少个\(b_i\)以及不 ...
- LTS1.3秘钥导出和身份验证计算过程
具体的参照描述协议规范文档 TLS1.3 RCF:8446 最新一版 协议描述的密钥推导计算流程图: TLS1.3内部非复杂程度难以想象.到底CPN Tools能否支撑分析TLS,我现在从新要整 ...
- koa-generator - koa 脚手架
koa-generator - koa 脚手架 npm install -g koa-generator 创建 koa2 /tmp/foo && cd /tmp/foo 资料: 基于N ...
- win10 有 休眠 功能,将内存保存到文件,开机10秒左右,恢复之前idea等所有软件
休眠 休眠 休眠 重要的事情说三遍. 提示,默认不显示,需要控制面板 电源里面设置下.