题目


分析

最直接的做法就是在线一边修改边权,询问直接全部重排,

然后用可撤销并查集维护连通块大小,这样时间复杂度为 \(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]桥梁的更多相关文章

  1. [BZOJ4537][Hnoi2016]最小公倍数 奇怪的分块+可撤销并查集

    4537: [Hnoi2016]最小公倍数 Time Limit: 40 Sec  Memory Limit: 512 MBSubmit: 1474  Solved: 521[Submit][Stat ...

  2. 【简单数据结构】并查集--洛谷 P1111

    题目背景 AA地区在地震过后,连接所有村庄的公路都造成了损坏而无法通车.政府派人修复这些公路. 题目描述 给出A地区的村庄数NN,和公路数MM,公路是双向的.并告诉你每条公路的连着哪两个村庄,并告诉你 ...

  3. bzoj2049 线段树 + 可撤销并查集

    https://www.lydsy.com/JudgeOnline/problem.php?id=2049 线段树真神奇 题意:给出一波操作,拆边加边以及询问两点是否联通. 听说常规方法是在线LCT, ...

  4. CodeForces892E 可撤销并查集/最小生成树

    http://codeforces.com/problemset/problem/892/E 题意:给出一个 n 个点 m 条边的无向图,每条边有边权,共 Q 次询问,每次给出 ki​ 条边,问这些边 ...

  5. BZOJ4358: permu(带撤销并查集 不删除莫队)

    题意 题目链接 Sol 感觉自己已经老的爬不动了.. 想了一会儿,大概用个不删除莫队+带撤销并查集就能搞了吧,\(n \sqrt{n} logn\)应该卡的过去 不过不删除莫队咋写来着?....跑去学 ...

  6. 【离线 撤销并查集 线段树分治】bzoj1018: [SHOI2008]堵塞的交通traffic

    本题可化成更一般的问题:离线动态图询问连通性 当然可以利用它的特殊性质,采用在线线段树维护一些标记的方法 Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常 ...

  7. codeforces 892E(离散化+可撤销并查集)

    题意 给出一个n个点m条边的无向联通图(n,m<=5e5),有q(q<=5e5)个询问 每个询问询问一个边集{Ei},回答这些边能否在同一个最小生成树中 分析 要知道一个性质,就是权值不同 ...

  8. 【Codeforces576E_CF576E】Painting Edges(可撤销并查集+线段树分治)

    题目 CF576E 分析: 从前天早上肝到明天早上qwq其实颓了一上午MC ,自己瞎yy然后1A,写篇博客庆祝一下. 首先做这题之前推荐一道很相似的题:[BZOJ4025]二分图(可撤销并查集+线段树 ...

  9. 【BZOJ4025】二分图(可撤销并查集+线段树分治)

    题目: BZOJ4025 分析: 定理:一个图是二分图的充要条件是不存在奇环. 先考虑一个弱化的问题:保证所有边出现的时间段不会交叉,只会包含或相离. 还是不会?再考虑一个更弱化的问题:边只会出现不会 ...

  10. 算法笔记--可撤销并查集 && 可持久化并查集

    可撤销并查集模板: struct UFS { stack<pair<int*, int>> stk; int fa[N], rnk[N]; inline void init(i ...

随机推荐

  1. django学习第九天---raw查询原生sql和python脚本中调用django环境和ORM锁和事务

    ORM执行原生sql语句 在模型查询api不够用的情况下,我们还可以使用原始的sql语句进行查询 方式1 raw() raw()方法,返回模型的实例django.db.models.query.Raw ...

  2. 解决macOS Big Sur系统pyenv不能安装python3.6.x版本的问题及pyenv-virtualenv的安装使用

    前置 先安装好pyenv brew install pyenv 配置环境 echo -e 'if command -v pyenv 1>/dev/null 2>&1; then\n ...

  3. 【NLP学习其3.5】词嵌入的特性,为什么词之间会有联系?

    词嵌入的特性 现在你有了一堆嵌入向量,我们可以开始学习他们之间的特性了 前情提要:https://www.cnblogs.com/DAYceng/p/14962528.html 先把各向量重新命名便于 ...

  4. 【LeetCode栈与队列#01】队列的基本操作:用栈模拟队列和用队列模拟栈

    用栈实现队列 力扣题目链接(opens new window) 使用栈实现队列的下列操作: push(x) -- 将一个元素放入队列的尾部. pop() -- 从队列首部移除元素. peek() -- ...

  5. 记一次WPF集成SemanticKernel+OneAPI+讯飞星火认知大模型实践

    开启OneAPI服务 OneAPI介绍 OpenAI 接口管理 & 分发系统,支持 Azure.Anthropic Claude.Google PaLM 2 & Gemini.智谱 C ...

  6. MySQL 数据库死锁排查

    死锁排查方法 查看进程状态 show processlist; 查看行锁的状态 show status like 'InnoDB_row_lock%'; 查询是否有死锁 show engine inn ...

  7. curl比较有用的参数

     精选参数: --include // -i curl的输出中包含http头信息--verbose // 比-i更加丰富,>表示请求的信息, <表示curl接收的信息 *表示curl额外提 ...

  8. 独家消息:阿里云悄然推出RPA云电脑,已与多家RPA厂商开放合作

    独家消息:阿里云悄然推出RPA云电脑,已与多家RPA厂商开放合作 RPA云电脑,让RPA开箱即用算力无限? 文/王吉伟 这几天,王吉伟频道通过业内人士获得独家消息,阿里云近期推出了一个名为「RPA云电 ...

  9. Git 系列:简介安装以及配置管理

    目录 简介安装 简介 Centos安装 配置管理 git help 概要 选项 示例 git-doc git config 概要 选项 变量 示例 初始化配置 简介安装 简介 https://git- ...

  10. npm install --legacy-peer-deps 安装出现依赖包冲突的解决方案

    npm install --legacy-peer-deps 安装出现依赖包冲突的解决方案 为什么 在安装依赖包的时候,会有依赖包的冲突 比如A包引用了C的1.0版本 B包依赖了C的1.1版本 win ...