题目描述

N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数。

题解

对于一个截止时间来说,越晚的变越好。

所以我们可以维护一颗以边的序号为关键字的最大生成树,然后用主席树维护一下。

询问直接在R的主席树里查就可以了。

代码

#include<iostream>
#include<cstdio>
#include<cstring>
#define N 400002
using namespace std;
int f[N],a[N],n,m,type,k;
inline int rd(){
int x=;char c=getchar();bool f=;
while(!isdigit(c)){if(c=='-')f=;c=getchar();}
while(isdigit(c)){x=(x<<)+(x<<)+(c^);c=getchar();}
return f?-x:x;
}
inline int find(int x){return f[x]=f[x]==x?x:find(f[x]);}
struct LCT{
int ch[N][],fa[N],l[N],tr[N];bool rev[N];
#define ls ch[x][0]
#define rs ch[x][1]
inline bool ge(int x){return ch[fa[x]][]==x;}
inline bool isroot(int x){return ch[fa[x]][]!=x&&ch[fa[x]][]!=x;}
inline void pushup(int x){
tr[x]=x;
if(ls&&a[tr[ls]]<a[tr[x]])tr[x]=tr[ls];if(rs&&a[tr[rs]]<a[tr[x]])tr[x]=tr[rs];
}
inline void rotate(int x){
int y=fa[x],o=ge(x);
ch[y][o]=ch[x][o^];fa[ch[y][o]]=y;
if(!isroot(y))ch[fa[y]][ge(y)]=x;fa[x]=fa[y];
fa[y]=x;ch[x][o^]=y;pushup(y);pushup(x);
}
inline void pushdown(int x){if(rev[x]){rev[x]^=;rev[ls]^=;rev[rs]^=;swap(ls,rs);}}
inline void _pushdown(int x){if(!isroot(x))_pushdown(fa[x]);pushdown(x);}
inline void splay(int x){
_pushdown(x);
while(!isroot(x)){
int y=fa[x];
if(isroot(y))rotate(x);
else rotate(ge(x)==ge(y)?y:x),rotate(x);
}
}
inline int findroot(int x){
access(x);splay(x);pushdown(x);
while(ls)x=ls,pushdown(x);return x;
}
inline void access(int x){for(int y=;x;y=x,x=fa[x])splay(x),ch[x][]=y,pushup(x);}
inline void makeroot(int x){access(x);splay(x);rev[x]^=;}
inline void split(int x,int y){makeroot(x);access(y);splay(y);}
inline void link(int x,int y){makeroot(x);fa[x]=y;}
inline void cut(int x,int y){split(x,y);fa[x]=ch[y][]=;pushup(y);}
void dfs(int x){
if(ls)dfs(ls);cout<<x<<" ";if(rs)dfs(rs);
}
#undef ls
#undef rs
}lct;
int tot,ls[N*],rs[N*],sum[N*],T[N],ans;
void upd(int &cnt,int pre,int l,int r,int x,int y){
cnt=++tot;ls[cnt]=ls[pre];rs[cnt]=rs[pre];sum[cnt]=sum[pre]+y;
if(l==r)return;
int mid=(l+r)>>;
if(mid>=x)upd(ls[cnt],ls[pre],l,mid,x,y);
else upd(rs[cnt],rs[pre],mid+,r,x,y);
}
int query(int cnt,int l,int r,int L,int R){
if(l>=L&&r<=R)return sum[cnt];
int mid=(l+r)>>,ans=;
if(mid>=L)ans+=query(ls[cnt],l,mid,L,R);
if(mid<R)ans+=query(rs[cnt],mid+,r,L,R);
return ans;
}
struct edge{int x,y;}b[N];
int main(){
n=rd();m=rd();k=rd();type=rd();
for(int i=;i<=n;++i)f[i]=i;int x,y;
for(int i=;i<=n;++i)a[i]=2e9;
for(int i=;i<=m;++i){
a[i+n]=i;
x=rd();y=rd();T[i]=T[i-];b[i].x=x;b[i].y=y;
if(x==y)continue;
if(find(x)==find(y)){
lct.split(x,y);
int id=lct.tr[y];
// lct.dfs(y);cout<<" ??? "<<x<<" "<<y<<" "<<id<<" "<<lct.findroot(y)<<endl;
lct.cut(id,b[id-n].x);lct.cut(id,b[id-n].y);upd(T[i],T[i],,m,id-n,-);
lct.link(x,i+n);lct.link(y,i+n);
}else{
lct.link(x,i+n);lct.link(y,i+n);
int xx=find(x),yy=find(y);f[xx]=yy;
}
upd(T[i],T[i],,m,i,);
}
for(int i=;i<=k;++i){
x=rd();y=rd();if(type)x^=ans,y^=ans;
printf("%d\n",ans=n-query(T[y],,m,x,y));
}
return ;
}

bzoj3514(LCT+主席树)的更多相关文章

  1. [BZOJ3514]CodeChef MARCH14 GERALD07加强版(LCT+主席树)

    3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 2177  Solved: 834 ...

  2. 【BZOJ3514】Codechef MARCH14 GERALD07加强版 LCT+主席树

    题解: 还是比较简单的 首先我们的思路是 确定起点 然后之后贪心的选择边(也就是越靠前越希望选) 我们发现我们只需要将起点从后向前枚举 然后用lct维护连通性 因为强制在线,所以用主席树记录状态就可以 ...

  3. BZOJ3514:GERALD07加强版(LCT,主席树)

    Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密. 接下来 ...

  4. [bzoj3514][CodeChef GERALD07] Chef ans Graph Queries [LCT+主席树]

    题面 bzoj上的强制在线版本 思路 首先可以确定,这类联通块相关的询问问题,都可以$LCT$+可持久化记录解决 用LCT维护生成树作为算法基础 具体而言,从前往后按照边的编号顺序扫一遍边 如果这条边 ...

  5. BZOJ 3514: Codechef MARCH14 GERALD07加强版 [LCT 主席树 kruskal]

    3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 1312  Solved: 501 ...

  6. 洛谷P4180 [Beijing2010组队]次小生成树Tree(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)

    洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...

  7. BZOJ 3514: Codechef MARCH14 GERALD07加强版(LCT + 主席树)

    题意 \(N\) 个点 \(M\) 条边的无向图,询问保留图中编号在 \([l,r]\) 的边的时候图中的联通块个数. \(K\) 次询问强制在线. \(1\le N,M,K \le 200,000\ ...

  8. 洛谷P4180 [BJWC2010]次小生成树(最小生成树,LCT,主席树,倍增LCA,倍增,树链剖分)

    洛谷题目传送门 %%%TPLY巨佬和ysner巨佬%%% 他们的题解 思路分析 具体思路都在各位巨佬的题解中.这题做法挺多的,我就不对每个都详细讲了,泛泛而谈吧. 大多数算法都要用kruskal把最小 ...

  9. BZOJ 3514 GERALD07加强版 (LCT+主席树)

    题目大意:给定n个点m条边无向图,每次询问求当图中有编号为[L,R]的边时,整个图的联通块个数,强制在线 神题!(发现好久以前的题解没有写完诶) 我们要求图中联通块的个数,似乎不可搞啊. 联通块个数= ...

随机推荐

  1. PAT L2-016 愿天下有情人都是失散多年的兄妹

    https://pintia.cn/problem-sets/994805046380707840/problems/994805061769609216 呵呵.大家都知道五服以内不得通婚,即两个人最 ...

  2. Docker存储驱动Device Mapper,Overlay,AUFS

    Docker存储驱动之Device Mapper简介 - BookShu - 博客园https://www.cnblogs.com/styshoo/p/6528762.html Docker存储驱动之 ...

  3. package-lock.json和package.json的作用

    转自:https://www.cnblogs.com/cangqinglang/p/8336754.html package-lock.json的作用就是锁定安装依赖时包的版本,并且需要上传到git, ...

  4. 用Canvas实现一些简单的图片滤镜

    1.灰度滤镜 对于灰度滤镜的实现一般有三种算法 1) 最大值法:即新的颜色值R=G=B=Max(R,G,B),通过这种方法处理后的图片看起来亮度值偏高. 2) 平均值法:即新的颜色值R=G=B=(R+ ...

  5. python之路--subprocess,粘包现象与解决办法,缓冲区

    一. subprocess 的简单用法 import subprocess sub_obj = subprocess.Popen( 'dir', #系统指令 shell=True, #固定方法 std ...

  6. django rest framework批量上传图片及导入字段

    一.项目需求 批量上传图片,然后批量导入(使用excel)每个图片对应的属性(属性共十个,即对应十个字段,其中外键三个). 二.问题 一次可能上传成百上千张图片和对应字段,原来数据库的设计我将图片和对 ...

  7. 使用PHP对二维索引数组进行排序

    本例中 data 数组中的每个单元表示一个表中的一行.这是典型的数据库记录的数据集合. 例子中的数据如下: volume | edition -------+-------- 67 | 2 86 | ...

  8. vue-cli: render:h => h(App)是什么意思

    import Vue from 'vue' import App from './App.vue' Vue.config.productionTip = false new Vue({ render: ...

  9. Lodop输出页面input文本框的最新值

    默认使用Lodop打印页面上的文本框等,会发现虽然页面上文本框输入了值,打印预览却是空的,这是由于没有把最新的值传入Lodop. 如图,演示的是Lodop如何输出文本框内的新值,这里整个页面只有inp ...

  10. Js返回上一页,刷新页面,定时刷新,改变地址栏 等常用实用技巧

    1. Javascript 返回上一页history.go(-1), 返回两个页面: history.go(-2); 2. history.back(). 3. window.history.forw ...