传送门

题目大意

给定一个$n$个点$m$条边的无向图$(n,m\leq 200000)$。

有$q$每次询问$(q\leq 200000)$,每次给定一个区间$L,R$,求仅保留编号$\in[L,R]$的边,原图连通块的数量。

题解

不难发现连通块数量可以通过总点数$-$最大生成森林的边集大小得到。

按照编号对边从小到大排序,用$LCT$动态维护最大生成森林,每次操作加边时,若两个点不连通,就直接连边即可。

否则,就把路径上编号最小的边断掉,再强行连上新的边。则当前的生成森林一定是最大的并且恰好覆盖了每一个连通块。

对于每一次询问,就是用$n$减去在最大的边编号为$R$时,最大生成森林中编号$\in[L,R]$的数量。

用主席树维护一下即可。复杂度$O((m+q)\log n)$。

由于在$LCT$中维护边权比较复杂,所以我们可以把一条边变成一个点,这个点连向原边的两段端点,点权即为边权,会方便许多。

#include<algorithm>
#include<iostream>
#include<cstring>
#include<cstdio>
#include<cmath>
#define LL long long
#define M 400020
#define INF 3000020
#define ls c[x][0]
#define rs c[x][1]
#define mid ((l+r)>>1)
using namespace std;
int read(){int nm=0,fh=1; char cw=getchar();for(;!isdigit(cw);cw=getchar()) if(cw=='-') fh=-fh;for(;isdigit(cw);cw=getchar()) nm=nm*10+(cw-'0');return nm*fh;
}
void write(int x){if(x>9) write(x/10);putchar(x%10+'0');}
int n,m,fa[M],c[M][2],u[M],v[M],e[M],rev[M];
int L[M*30],R[M*30],sum[M*30],cnt,rt[M],S[M],top,tot;
void pushup(int x){if(x) e[x]=(x>n?x-n:INF),e[x]=min(e[x],min(e[ls],e[rs]));}
void pushdown(int x){if(rev[x]&&x) rev[x]=0,rev[ls]^=1,rev[rs]^=1,swap(ls,rs);}
bool isroot(int x){return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;}
void rotate(int x){int tp=fa[x],dtp=fa[fa[x]],ms,ds;if(c[dtp][0]==tp) c[dtp][0]=x;else if(c[dtp][1]==tp) c[dtp][1]=x;if(c[tp][0]==x) ms=0,ds=1;else ms=1,ds=0;fa[x]=dtp,fa[tp]=x,fa[c[x][ds]]=tp;c[tp][ms]=c[x][ds],c[x][ds]=tp;pushup(tp),pushup(x);
}
void splay(int x){S[top=1]=x;for(int y=x;!isroot(y);y=fa[y]) S[++top]=fa[y];while(top) pushdown(S[top]),top--;while(!isroot(x)){int tp=fa[x];if(isroot(tp)) return rotate(x);else if(c[c[fa[tp]][0]][0]==x) rotate(tp);else if(c[c[fa[tp]][1]][1]==x) rotate(tp);else rotate(x);}
}
int fdrt(int x){return fa[x]?fdrt(fa[x]):x;}
void access(int x){for(int y=0;x;y=x,x=fa[x]) splay(x),rs=y,pushup(x);}
void chroot(int x){access(x),splay(x),rev[x]^=1;}
void link(int x,int y){chroot(x),splay(x),fa[x]=y;}
void cut(int x,int y){chroot(x),access(y),splay(x),fa[y]=ls=rs=c[y][0]=c[y][1]=0,pushup(x),pushup(y);}
int qry(int x,int y){chroot(x),access(y),splay(x);return (fdrt(y)!=x)?0:e[x];}
void ins(int &x,int pre,int l,int r,int pos,int dt){x=++cnt,L[x]=L[pre],R[x]=R[pre];sum[x]=sum[pre]+dt; if(l==r) return;if(pos<=mid)ins(L[x],L[pre],l,mid,pos,dt);else ins(R[x],R[pre],mid+1,r,pos,dt);
}
int getans(int x,int l,int r,int minn){if(r<minn||!sum[x]) return 0; if(l>=minn) return sum[x];return getans(L[x],l,mid,minn)+getans(R[x],mid+1,r,minn);
}
int main(){for(int T=read(),Q;T;T--,cnt=0){n=read(),m=read(),Q=read(),tot=n,memset(c,0,sizeof(c));memset(rt,0,sizeof(rt)),memset(fa,0,sizeof(fa)),memset(e,0x3f,sizeof(e));for(int i=1;i<=m;i++){int now; u[i]=read(),v[i]=read(),rt[i]=rt[i-1],tot++;if(u[i]==v[i]) continue; now=qry(u[i],v[i]);if(now)  ins(rt[i],rt[i],1,m,now,-1),cut(u[now],v[now]);ins(rt[i],rt[i],1,m,i,1),link(u[i],tot),link(v[i],tot);}while(Q--){int tl=read(),tr=read(),num;num=getans(rt[tr],1,m,tl);write(n-num),putchar('\n');}}return 0;
}

转载于:https://www.cnblogs.com/OYJason/p/9744840.html

Code Chef - Chef and Graph Queries相关推荐

  1. CFCC百套计划2 CodeChef December Challenge 2017 Chef And Easy Xor Queries

    https://www.codechef.com/DEC17/problems/CHEFEXQ 题意: 位置i的数改为k 询问区间[1,i]内有多少个前缀的异或和为k 分块 sum[i][j] 表示第 ...

  2. 利用 Chef 在 Red Hat Enterprise Linux 上自动化部署 Mariadb Galera Cluster

    简介 Chef Chef提供了一套自动化安装和配置软件的工具.它允许开发者以模块化的方式(cookbook)来定义软件的安装和配置流程(recipe),以及流程中的可定制参数(attribute).当 ...

  3. Chef集中管理工具实践

     Chef集中管理工具实践之 (0) 什么是Chef 目录结构 Chef集中管理工具实践之 (0) 什么是Chef Chef集中管理工具实践之 (1) 环境部署 Chef集中管理工具实践之 (2) ...

  4. Puppet SaltStack Chef Ansible

    随着服务器集群规模越来越大,自动化配置和部署这些服务器能够使管理变得非常容易并大大减小管理部署成本,因而得到 IT 公司的高度重视. 目前,市场上主流的四大开源自动化配置管理工具有:Puppet.Ch ...

  5. Chef学习之六:Knife cookbook

    开始学习cookbook了(http://docs.opscode.com/essentials_cookbook_directory.html) 官方文档介绍了3个命令,本以为很容易,没想到费了一番 ...

  6. 计算机视觉与模式识别方面的代码code

    UIUC的Jia-Bin Huang同学收集了很多计算机视觉方面的代码,链接如下: https://netfiles.uiuc.edu/jbhuang1/www/resources/vision/in ...

  7. 785. Is Graph Bipartite? 判断二分图

    Title 给定一个无向图graph,当这个图为二分图时返回true. 如果我们能将一个图的节点集合分割成两个独立的子集A和B,并使图中的每一条边的两个节点一个来自A集合,一个来自B集合,我们就将这个 ...

  8. 计算机视觉和模式识别的code

     [转]计算机视觉和模式识别的code UIUC的Jia-Bin Huang同学收集了很多计算机视觉方面的代码,链接如下: https://netfiles.uiuc.edu/jbhuang1/w ...

  9. 英文邮件模板--向论文作者索要源代码(write an email requesting for code)

    主题: Dear Professor: Hello, my name is XXX. May everything is good with you. I am an undergraduate of ...

  10. A Transformer-based Approach for Source code Summarization 翻译

    A Transformer-based Approach for Source Code Summarization 全文翻译 本文最佳阅读方式:读完一段中文内容快速阅读对应的英文部分 欢迎关注我的公 ...

最新文章

  1. python输出结果空格分割_python 输出列表元素实例(以空格/逗号为分隔符)
  2. 剑指offer:链表中倒数第k个结点 python实现
  3. Codeforces Round #703 (Div. 2) B.Eastern Exhibition 中位数结论
  4. mysql临时表空间_MySQL 5.7 深度解析: 临时表空间
  5. 什么是JSONP以及它是怎么产生的
  6. python time 时间差,python如何计算时间差
  7. 一行Python代码能干什么?惊了!
  8. 【Python爬虫学习笔记(3)】Beautiful Soup库相关知识点总结
  9. 用gpg加密软件加密文件
  10. PLSQL 使用技巧(快捷键/关键字等)
  11. 简历在线制作计算机,简历在线生成,在线生成PDF或word格式简历
  12. cpu顶盖怎么看步进_CPU步进是什么意思?i3-9100F B0步进和U0步进区别知识科普
  13. SEO中一些黑帽作弊方法介绍
  14. geoserver样式(SLD方式)—— 图层元素在不同比例尺显示不同样式
  15. java实现正态分布累积分布,标准正态分布变量的累积概率分布函数
  16. 支付宝小程序对接流程和工具类
  17. linux脚本-z,shell脚本中的-a到-z的意思
  18. html5新增标签有dfn吗,html元素dfn标签的使用方法及作用
  19. 学习Chrome Devtools 调试
  20. 苹果申请屏幕防指纹专利 互联网信用体系跨越一大步

热门文章

  1. 十八、K8s升级集群
  2. MySQL读写分离详解(二)——MyCAT实战配置
  3. HTTP协议基本原理简介(二)
  4. 关于配置了数据库方言为MySQLInnoDBDialect后Hibernate不能自动建表的问题
  5. MAC 终端打开sublime3
  6. 把SWT包装成Plugin需要修改的地方
  7. Android自定义ToolBar布局
  8. Linux学习记录--ACL权限控制
  9. 小马儿随笔(七)——综合布线的安装时代
  10. 君子抉(4月28日)