欢迎访问~原文出处——博客园-zhouzhendong

去博客园看该题解


题目传送门 - BZOJ3514


题意概括

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

  N,M,Q<=200000


题解

  http://hzwer.com/4358.html

  这题hzwer还是写的很好的……


代码

#include <cstring>
#include <cstdio>
#include <cstdlib>
#include <algorithm>
#include <cmath>
using namespace std;
const int N=200005,S=N*2,Inf=23333333;
int n,m,k,type,prev_e[N];
struct Edge{
int x,y;
}e[N];
int fa[S],son[S][2],rev[S],val[S],Min[S];
void clear(int x,int v){
fa[x]=son[x][0]=son[x][1]=rev[x]=0;
val[x]=Min[x]=v;
}
bool isroot(int x){
return son[fa[x]][0]!=x&&son[fa[x]][1]!=x;
}
void pushup(int x){
Min[x]=min(val[x],min(Min[son[x][0]],Min[son[x][1]]));
}
void pushdown(int x){
if (rev[x]){
rev[x]=0;
rev[son[x][0]]^=1;
rev[son[x][1]]^=1;
swap(son[x][0],son[x][1]);
}
}
void pushadd(int x){
if (!isroot(x))
pushadd(fa[x]);
pushdown(x);
}
int wson(int x){
return son[fa[x]][1]==x;
}
void rotate(int x){
if (isroot(x))
return;
int y=fa[x],z=fa[y],L=wson(x),R=L^1;
if (!isroot(y))
son[z][wson(y)]=x;
fa[x]=z,fa[y]=x,fa[son[x][R]]=y;
son[y][L]=son[x][R],son[x][R]=y;
pushup(y),pushup(x);
}
void splay(int x){
pushadd(x);
for (int y=fa[x];!isroot(x);rotate(x),y=fa[x])
if (!isroot(y))
rotate(wson(x)==wson(y)?y:x);
}
void access(int x){
int t=0;
while (x){
splay(x);
son[x][1]=t;
pushup(x);
t=x;
x=fa[x];
}
}
int find(int x){
access(x);
splay(x);
while (son[x][0])
x=son[x][0];
return x;
}
void rever(int x){
access(x);
splay(x);
rev[x]^=1;
}
void link(int x,int y){
rever(x);
fa[x]=y;
}
void split(int x,int y){
rever(x);
access(y);
splay(y);
}
void cut(int x,int y){
split(x,y);
fa[x]=son[y][0]=0;
}
const int T=5200005;
int ls[T],rs[T],sum[T],root[N],total;
void Tpushup(int rt){
sum[rt]=sum[ls[rt]]+sum[rs[rt]];
}
void build(int &rt,int L,int R){
rt=++total;
if (L==R){
ls[T]=rs[T]=sum[T]=0;
return;
}
int mid=(L+R)>>1;
build(ls[rt],L,mid);
build(rs[rt],mid+1,R);
Tpushup(rt);
}
void add(int prt,int &rt,int L,int R,int pos){
rt=++total;
if (L==R){
sum[rt]=sum[prt]+1;
return;
}
int mid=(L+R)>>1;
if (pos<=mid)
add(ls[prt],ls[rt],L,mid,pos),rs[rt]=rs[prt];
else
add(rs[prt],rs[rt],mid+1,R,pos),ls[rt]=ls[prt];
Tpushup(rt);
}
int query(int rt,int L,int R,int pos){
if (R<=pos)
return sum[rt];
if (L>pos)
return 0;
int mid=(L+R)>>1;
return query(ls[rt],L,mid,pos)+query(rs[rt],mid+1,R,pos);
}
int main(){
scanf("%d%d%d%d",&n,&m,&k,&type);
for (int i=1;i<=m;i++)
scanf("%d%d",&e[i].x,&e[i].y);
int s=n+m;
for (int i=0;i<S;i++)
clear(i,Inf);
for (int i=1;i<=m;i++){
int x=e[i].x,y=e[i].y;
if (x==y){
prev_e[i]=i;
continue;
}
if (find(x)==find(y)){
split(y,x);
int ce=prev_e[i]=Min[x];
cut(e[ce].x,ce+n);
cut(e[ce].y,ce+n);
}
else
prev_e[i]=0;
clear(i+n,i);
link(x,i+n);
link(y,i+n);
}
total=n-1;
build(root[0],0,m);
for (int i=1;i<=m;i++)
add(root[i-1],root[i],0,m,prev_e[i]);
int lastans=0;
for (int i=1;i<=k;i++){
int L,R;
scanf("%d%d",&L,&R);
if (type)
L^=lastans,R^=lastans;
int res=query(root[R],0,m,L-1)-query(root[L-1],0,m,L-1);
res=n-res;
printf("%d\n",lastans=res);
}
return 0;
}

  

BZOJ3514 Codechef MARCH14 GERALD07加强版 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预处理+主席树

    Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec  Memory Limit: 256 MBSubmit: 1951  Solved: 746[Submi ...

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

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

  4. BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT+可持久化线段树

    自己独自想出来并切掉还是很开心的~ Code: #include <bits/stdc++.h> #define N 400005 #define inf 1000000000 #defi ...

  5. BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT维护最大生成树 主席树

    题面 考虑没有询问,直接给你一个图问联通块怎么做. 并查集是吧. 现在想要动态地做,那么应该要用LCT. 考虑新加进来一条边,想要让它能够减少一个联通块的条件就是现在边的两个端点还没有联通. 如果联通 ...

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

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

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

    从左到右加边, 假如+的边e形成环, 那么记下这个环上最早加入的边_e, 当且仅当询问区间的左端点> _e加入的时间, e对答案有贡献(脑补一下). 然后一开始是N个连通块, 假如有x条边有贡献 ...

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

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

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

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

随机推荐

  1. 列表控件QListWidget

    列表控件可以让我们以列表形式呈现内容,是界面更加有序美观.QListWidget列表控件应当与QListWidgetItem一起使用,后者作为项被添加入列表控件中,也就是说列表控件中的每一项都是一个Q ...

  2. JavaScript之this,call,apply

    this:被调用的上下文对象: apply与call:切换被调用的上下文对象,即 调用时,this被临时性地切换 //demo 1 [call] function forEach(list,callb ...

  3. 深入理解 RecyclerView 系列之:ItemDecoration

    https://blog.piasy.com/2016/03/26/Insight-Android-RecyclerView-ItemDecoration/?utm_source=tuicool&am ...

  4. android greenDao使用

    github:https://github.com/greenrobot/greenDAO 基本使用:https://toutiao.io/posts/yg1kyu/preview https://b ...

  5. 【逆向知识】GitHub:Awesome-Hacking(黑客技能列表-逆向)

    0 初衷 GitHub这一份黑客技能列表很不错,包含了多个方向的安全.但目前我关注只有逆向工程与恶意代码,所以其他的被暂时略过. 虽然很感谢作者的辛勤付出,但并不打算复制粘贴全套转载.逐条整理是为了从 ...

  6. 使用 GDebi 默认代替 Ubuntu 软件中心

    GDebi,一个安装 Debian 可执行文件的专用程序.它极其轻量,且专注于安装 .deb 文件,可以自动解决依赖问题,比原生的好用.GDebi 最有用的功能是它也可以为你展示出将要安装的程序的依赖 ...

  7. java工程操作redis

    启动redis服务 redis-server redis.windows.conf 添加驱动 <dependency> <groupId>redis.clients</g ...

  8. 一步步实现windows版ijkplayer系列文章之四——windows下编译ijkplyer版ffmpeg

    一步步实现windows版ijkplayer系列文章之一--Windows10平台编译ffmpeg 4.0.2,生成ffplay 一步步实现windows版ijkplayer系列文章之二--Ijkpl ...

  9. 转载:小结(1.7)《深入理解Nginx》(陶辉)

    原文:https://book.2cto.com/201304/19622.html 本章介绍了Nginx的特点以及在什么场景下需要使用Nginx,同时介绍了如何获取Nginx以及如何配置.编译.安装 ...

  10. Ex 5_26 变量约束是否能同时满足(并查集)_第九次作业

    利用并查集进行处理,定义一个维护数组components,components[i]表示变量序号为i的变量所处的集合,首先处理相等的变量,把它们放入同一个集合中,最后再处理不相等变量,若两个不相等的变 ...