BZOJ 3514 GERALD07加强版 (LCT+主席树)
题目大意:给定n个点m条边无向图,每次询问求当图中有编号为[L,R]的边时,整个图的联通块个数,强制在线
神题!(发现好久以前的题解没有写完诶)
我们要求图中联通块的个数,似乎不可搞啊。
联通块个数=n-树边条数!
考虑每条边的贡献,我们按编号从小到大暴力枚举每一条边。
考虑用$LCT$维护森林。
设新加入的这条边编号为$e$,连接了$x,y$两个点
如果$x,y$原来不连通,说明加入$e$会让图中多一条树边。边e对$L\in [1,e],R\geq e$的图$[L,R]$产生一点贡献
如果$x,y$原来就联通,说明加入$e$会产生环,并不会影响联通块个数。我们找出$e$所在环里编号最小的边$x$
当$L\leq x$时,删掉边$x$,图$[L,R]$的树边个数不变。
当$L>x$时,删掉边$x$,会让图$[L,R]$少一条树边。那么边$x$会对$L\in[x+1,e],R\geq e$的的图$[L,R]$产生一点贡献
如何处理询问?我们可以用主席树,主席树不同的根作为右端点,线段树维护对左端点的贡献。每次查询,主席树相减,然后单点查询
如何维护贡献?主席树上打差分实现区间修改
如何维护编号最小的边?把边转化成点扔到$LCT$里就行啦
#include <queue>
#include <vector>
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N1 401000
#define M1 201000
#define S1 (N1<<1)
#define T1 (N1<<2)
#define ll long long
#define uint unsigned int
#define rint register int
#define ull unsigned long long
#define dd double
#define il inline
#define inf 1000000000
using namespace std; int gint()
{
int ret=,fh=;char c=getchar();
while(c<''||c>''){if(c=='-')fh=-;c=getchar();}
while(c>=''&&c<=''){ret=ret*+c-'';c=getchar();}
return ret*fh;
}
int n,m,T,type;
struct Edge{
int x[M1],y[M1],cte;
void ae(int u,int v)
{cte++;x[cte]=u,y[cte]=v;}
}E;
struct SEG{
int ls[N1*],rs[N1*],sum[N1*],root[N1],tot;
void pushup(int rt){sum[rt]=sum[ls[rt]]+sum[rs[rt]];}
void build(int l,int r,int &rt)
{
int mid=(l+r)>>; rt=++tot;
if(l==r) return;
build(l,mid,ls[rt]);
build(mid+,r,rs[rt]);
}
void update(int x,int l,int r,int r1,int &r2,int w)
{
if((!r2)||(r1==r2)){r2=++tot,sum[r2]=sum[r1],ls[r2]=ls[r1],rs[r2]=rs[r1];}
if(l==r) {sum[r2]+=w; return;} int mid=(l+r)>>;
if(x<=mid) update(x,l,mid,ls[r1],ls[r2],w);
else update(x,mid+,r,rs[r1],rs[r2],w);
pushup(r2);
}
int query(int L,int R,int l,int r,int rt)
{
if(!rt||L>R) return ;
if(L<=l&&r<=R) return sum[rt];
int mid=(l+r)>>,ans=;
if(L<=mid) ans+=query(L,R,l,mid,ls[rt]);
if(R>mid) ans+=query(L,R,mid+,r,rs[rt]);
return ans;
}
}s;
namespace lct{
int ch[N1][],fa[N1],mi[N1],id[N1],rev[N1],tot;
int idf(int x){return ch[fa[x]][]==x?:;}
int isroot(int x){return (ch[fa[x]][]==x||ch[fa[x]][]==x)?:;}
void pushup(int x){mi[x]=min(x,min(mi[ch[x][]],mi[ch[x][]]));}
void revers(int x){swap(ch[x][],ch[x][]),rev[x]^=;}
void pushdown(int x){if(rev[x]){revers(ch[x][]),revers(ch[x][]),rev[x]^=;}}
void rot(int x)
{
int y=fa[x],ff=fa[y],px=idf(x),py=idf(y);
if(!isroot(y)) ch[ff][py]=x; fa[x]=ff;
fa[ch[x][px^]]=y,ch[y][px]=ch[x][px^];
ch[x][px^]=y,fa[y]=x;
pushup(y),pushup(x);
}
int stk[N1],tp;
void splay(int x)
{
int y=x; stk[++tp]=x;
while(!isroot(y)){stk[++tp]=fa[y],y=fa[y];}
while(tp){pushdown(stk[tp--]);}
while(!isroot(x))
{
y=fa[x];
if(isroot(y)) rot(x);
else if(idf(y)==idf(x)) rot(y),rot(x);
else rot(x),rot(x);
}
}
void access(int x){for(int y=;x;y=x,x=fa[x]) splay(x),ch[x][]=y,pushup(x);}
void mkroot(int x){access(x),splay(x),revers(x);}
void split(int x,int y){mkroot(x),access(y),splay(y);}
int fdroot(int x){access(x),splay(x);while(ch[x][])pushdown(ch[x][]),x=ch[x][];return x;}
void cut(int x,int y){split(x,y);fa[x]=ch[y][]=,pushup(y);}
void link(int x,int y){split(x,y);fa[x]=y;}
//int isconn(int x,int y){split(x,y);if(!ch[x][1]&&fa[x]=y&&ch[y][0]==x) return 1;}
void solve(int x,int y,int e)
{
split(x+m,y+m);
if(x==y){
int r1=s.root[e-],r2=s.root[e]=++s.tot;
s.sum[r2]=s.sum[r1],s.ls[r2]=s.ls[r1],s.rs[r2]=s.rs[r1];
}else if(fdroot(y+m)!=x+m){
s.update(,,m,s.root[e-],s.root[e],);
if(e<m) s.update(e+,,m,s.root[e-],s.root[e],-);
}else{
int id=mi[y+m],xx=E.x[id],yy=E.y[id];
cut(id,xx+m); cut(id,yy+m);
s.update(id+,,m,s.root[e-],s.root[e],);
if(e<m) s.update(e+,,m,s.root[e-],s.root[e],-);
}
link(e,x+m),link(e,y+m);
}
};
int tot; int main()
{
int i,j,x,y,Q,sx,sy,ans=; tot=n+m;
scanf("%d%d%d%d",&n,&m,&Q,&type);
for(j=;j<=m;j++) x=gint(), y=gint(), E.ae(x,y);
s.build(,m,s.root[]);
for(lct::mi[]=inf,i=;i<=n+m;i++) lct::mi[i]=i;
for(j=;j<=m;j++)
{
x=E.x[j]; y=E.y[j];
lct::solve(x,y,j);
}
for(j=;j<=Q;j++)
{
x=gint(), y=gint();
if(type) x^=ans,y^=ans;
sx=s.query(,x,,m,s.root[x-]);
sy=s.query(,x,,m,s.root[y]);
ans=n-(sy-sx);
printf("%d\n",ans);
}
return ;
}
BZOJ 3514 GERALD07加强版 (LCT+主席树)的更多相关文章
- BZOJ 3514: Codechef MARCH14 GERALD07加强版 [LCT 主席树 kruskal]
		3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 1312 Solved: 501 ... 
- BZOJ 3514: Codechef MARCH14 GERALD07加强版( LCT + 主席树 )
		从左到右加边, 假如+的边e形成环, 那么记下这个环上最早加入的边_e, 当且仅当询问区间的左端点> _e加入的时间, e对答案有贡献(脑补一下). 然后一开始是N个连通块, 假如有x条边有贡献 ... 
- [BZOJ3514]CodeChef MARCH14 GERALD07加强版(LCT+主席树)
		3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 2177 Solved: 834 ... 
- 【BZOJ3514】Codechef MARCH14 GERALD07加强版 LCT+主席树
		题解: 还是比较简单的 首先我们的思路是 确定起点 然后之后贪心的选择边(也就是越靠前越希望选) 我们发现我们只需要将起点从后向前枚举 然后用lct维护连通性 因为强制在线,所以用主席树记录状态就可以 ... 
- BZOJ3514:GERALD07加强版(LCT,主席树)
		Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密. 接下来 ... 
- GERALD07加强版:lct,主席树,边化点
		Description:N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. 传送门. lct这么神仙的东西一个题解都不写怎么行??? 神仙思路啊. 其实不是很难但是的确不容 ... 
- bzoj 3514: GERALD07加强版 lct+可持久化线段树
		题目大意: N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. 题解: 这道题考试的时候没想出来 于是便爆炸了 结果今天下午拿出昨天准备的题表准备做题的时候 题表里就有这题 ... 
- BZOJ_3514_Codechef MARCH14 GERALD07加强版_主席树+LCT
		BZOJ_3514_Codechef MARCH14 GERALD07加强版_主席树+LCT Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. I ... 
- 【BZOJ-3514】Codechef MARCH14 GERALD07加强版    LinkCutTree + 主席树
		3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 1288 Solved: 490 ... 
随机推荐
- Effective C++ 45-48
			45.弄清c++在幕后为你所写.所调用的函数. 假设设置一个空类,c++编译器会声明下面函数:拷贝构造函数.赋值运算符,析构函数,一对取地址运算符函数(const和非const).而假设你没有声明不论 ... 
- 游戏人生(一),我的lua之旅:那些坑爹的CCBReaderLoad
			首先,我们说说这个CCBReaderLoad. 这个脚本是cocos2dx自带的一个lua+cocosbuilder 的工具,详细功能呐,往下看. 先来看下我遇到的一个问题: ----美工给了我一个. ... 
- com关于引用计数
			实现引用计数并不难,但在什么层次上进行引用计数呢? 依照com规范,一个com组件能够实现多个com对象.而且每一个com对象又能够支持多个com接口,这样的层次结构为我们实现引用计数提供了多种选择方 ... 
- Wireshark抓取RTP包,还原语音
			最近在做基于SIP的VoIP通信研究,使用Wireshark软件可以对网络流量进行抓包. VoIP使用RTP协议对语音数据进行传输,语音载荷都封装在RTP包里面.要对传输中的语音进行截获和还原,需要通 ... 
- B. Jeff and Periods(cf)
			B. Jeff and Periods time limit per test 1 second memory limit per test 256 megabytes input standard ... 
- sublime text 快键键
			sublime text 的快捷键ctrl+l 选择整行(按住-继续选择下行)ctrl+shift+k ... 
- POJ 3468 线段树+状压
			题意:给你n个数,有对区间的加减操作,问某个区间的和是多少. 思路:状压+线段树(要用lazy标记,否则会TLE) //By SiriusRen #include <cstdio> #in ... 
- Tomcat  程序无问题的情况下页面打开变慢的原因
			看看这写日志的频率就知道我有多闲了.. 前言: 其实关于tomcat,遇到过很多关于“慢”的问题,比如启动慢,比如页面打开慢, 以前太忙也太懒,不愿意花时间分析原因,现在终于肯静下来找原因 环境是ec ... 
- SQLServer2008 字符串函数一览表
			/* 字符串函数 (PS.索引都从1开始计算)*/ /* 指定字符(或字符串)A.字符串B.起始索引.获得A在B中的索引值.*/select Charindex('d','abcdefg',0) -- ... 
- P2241 统计方形(数据加强版)
			题目背景 1997年普及组第一题 题目描述 有一个n*m方格的棋盘,求其方格包含多少正方形.长方形 输入输出格式 输入格式: n,m因为原来数据太弱,现规定m小于等于5000,n小于等于5000(原来 ... 
