#include <iostream>
#include <cstdio>
#include <cstring>
#include <cmath>
#include <algorithm>
#define maxn 400005
#define maxm 200005
#define maxk 4000005
using namespace std; int n,m,k,type,ans,Ans,size,fa[maxn],son[maxn][],sm[maxn],Val[maxm],val[maxn],sum[maxk],root[maxm],lc[maxk],rc[maxk];
bool rev[maxn];
struct date{
int u,v;
}wi[maxm]; struct note{
bool which(int x){
return son[fa[x]][]==x;
}
bool isroot(int x){
return son[fa[x]][]!=x&&son[fa[x]][]!=x;
}
void update(int x){
sm[x]=val[x];
if (son[x][]) sm[x]=min(sm[x],sm[son[x][]]);
if (son[x][]) sm[x]=min(sm[x],sm[son[x][]]);
}
void pushdown(int x){
if (!rev[x]) return;
rev[x]^=,swap(son[x][],son[x][]);
if (son[x][]) rev[son[x][]]^=;
if (son[x][]) rev[son[x][]]^=;
}
void relax(int x){
if (!isroot(x)) relax(fa[x]);
pushdown(x);
}
void rotata(int x){
int y=fa[x],d=which(x),dd=which(y);
if (!isroot(y)) son[fa[y]][dd]=x; fa[x]=fa[y];
fa[son[x][d^]]=y,son[y][d]=son[x][d^];
fa[y]=x,son[x][d^]=y;
update(y);
}
void splay(int x){
relax(x);
while (!isroot(x)){
if (isroot(fa[x])) rotata(x);
else if (which(x)==which(fa[x])) rotata(fa[x]),rotata(x);
else rotata(x),rotata(x);
}
update(x);
}
void access(int x){
for (int p=;x;x=fa[x]){
splay(x);
son[x][]=p;
p=x;
update(x);
}
}
void make_root(int x){
access(x);
splay(x);
rev[x]^=;
}
void link(int x,int y){
make_root(x);
fa[x]=y;
}
void cut(int x,int y){
make_root(x);
access(y);
splay(y);
son[y][]=fa[x]=;
update(y);
}
void split(int x,int y){
make_root(x);
access(y);
splay(y);
}
int find_root(int x){
access(x);
splay(x);
while (son[x][]) x=son[x][];
return x;
}
int find(int x,int y){
split(x,y);
return sm[y];
}
}lct; void insert(int &k,int p,int l,int r,int x){
k=++size,sum[k]=sum[p]+;
int mid=(l+r)/;
if (l==r) return;
if (x<=mid) rc[k]=rc[p],insert(lc[k],lc[p],l,mid,x);
else lc[k]=lc[p],insert(rc[k],rc[p],mid+,r,x);
} void insert(int id,int x){
insert(root[id],root[id-],,m+,x);
} void Query(int k1,int k2,int l,int r,int x,int y){
if (!k1&&!k2) return;
if (l>=x&&r<=y){
Ans+=(sum[k2]-sum[k1]);
return;
}
int mid=(l+r)/;
if (x<=mid) Query(lc[k1],lc[k2],l,mid,x,y);
if (y>mid) Query(rc[k1],rc[k2],mid+,r,x,y);
} int query(int x,int y){
Ans=;
int u=root[x-],v=root[y],l=,r=m+,mid;
Query(u,v,l,r,,x-);
return Ans;
} int main(){
int u,v,t1,t2,temp;
scanf("%d%d%d%d",&n,&m,&k,&type);
memset(sum,,sizeof(sum));
memset(Val,,sizeof(Val));
memset(fa,,sizeof(fa));
memset(son,,sizeof(son));
memset(rev,,sizeof(rev));
for (int i=;i<=m;i++) scanf("%d%d",&wi[i].u,&wi[i].v);
for (int i=;i<=n;i++) val[i]=sm[i]=m+;
for (int i=;i<=m;i++) val[n+i]=sm[n+i]=i;
for (int i=;i<=m;i++){
u=wi[i].u,v=wi[i].v;
if (u==v) Val[i]=m+;
if (u==v) continue;
if (lct.find_root(u)!=lct.find_root(v)){
Val[i]=;
lct.link(n+i,u),lct.link(n+i,v);
}else{
temp=lct.find(u,v);
Val[i]=temp,temp+=n;
lct.cut(temp,wi[temp-n].u),lct.cut(temp,wi[temp-n].v);
lct.link(n+i,u),lct.link(n+i,v);
}
}
memset(root,,sizeof(root));
for (int i=;i<=m;i++){
insert(i,Val[i]);
}
ans=;
for (int i=;i<=k;i++){
scanf("%d%d",&u,&v);
if (type==) u^=ans,v^=ans;
if (u>v) swap(u,v);
ans=n-query(u,v);
printf("%d\n",ans);
}
return ;
}

题目链接:http://www.lydsy.com/JudgeOnline/problem.php?id=3514

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

做法:如果要求整个图中联通块的个数,记加入该边后不形成环的边数记为x,则答案为n-x,这题问的是加入编号为[l~r]中的边后联通块的个数,答案便稍微变化了一下,记能使联通块数目-1的边集为{S},答案为n-|S|,问题便成为了:有多少条边属于{S},仔细想想,可以先预处理一个数组val[i],怎么预处理呢?可以按编号依次加入边,有两种情况:*1.如果加入的这条边不形成环,则这条边的权值赋值为0,并加入这条边;*2.加入这条边形成环,记环上编号最小的边的编号为y,这加入的这条边权值为y,并删去编号最小的那条边,加入该边。这个过程用lct模拟即可,比较基础的操作。

得出每条边的权值val[i]后,对于一个询问[L~R],如果一条边的val<l,则该边属于{S},问题便简化为一个数组val,问在区间L~R中权值在0~L-1的个数,显而易见,可持久化线段树轻松搞定。问题得以圆满解决。(Lct+可持久化线段树)

bzoj3514Codechef MARCH14 GERALD07加强版的更多相关文章

  1. 【BZOJ-3514】Codechef MARCH14 GERALD07加强版 LinkCutTree + 主席树

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

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

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

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

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

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

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

  5. BZOJ_3514_Codechef MARCH14 GERALD07加强版_主席树+LCT

    BZOJ_3514_Codechef MARCH14 GERALD07加强版_主席树+LCT Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. I ...

  6. [BZOJ 3514]Codechef MARCH14 GERALD07加强版 (CHEF AND GRAPH QUERIES)

    [BZOJ3514] Codechef MARCH14 GERALD07加强版 (CHEF AND GRAPH QUERIES) 题意 \(N\) 个点 \(M\) 条边的无向图,\(K\) 次询问保 ...

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

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

  8. bzoj3514 Codechef MARCH14 GERALD07加强版 lct预处理+主席树

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

  9. BZOJ3514 : Codechef MARCH14 GERALD07加强版

    以边编号为权值 用Link-cut Tree维护最大生成树 对于新加的第i条边(u,v) a[i]表示当a[i]这条边加入后连通块个数会减少 若u==v则a[i]=m 若u与v不连通则连上,a[i]= ...

随机推荐

  1. 深入运用js

    1,eval()函数 这个函数是获取参数的字符串,并将其作为js来处理,所以这里就有可能有人用这个来搞破坏(比如注入JS脚本文件等),所以最好的是方法是尽量少用,或者可以用new function() ...

  2. 1927: [Sdoi2010]星际竞速

    1927: [Sdoi2010]星际竞速 Time Limit: 20 Sec  Memory Limit: 259 MBSubmit: 2040  Solved: 1257[Submit][Stat ...

  3. mssql 2008 复制订阅

    广域网的复制订阅 准备工作: 1.a.b服务器创建相同的系统用户密码 2.在a服务器 sql server 配置管理器 创建别名 ip填写b服务器的ip, b服务器端口号 3.在b服务器  sql s ...

  4. Ztree 随笔记

    Ztree方法是一个单体对象方法,假如一个页面有多个的话,每申明一个新对象前面的Ztree对象就要被覆盖. 解决:在生成tree控件的时候就要设置其控件ID,然后通过$.fn.zTree.getZTr ...

  5. mac:在当前文件夹打开terminal终端

    System Preferences -> Keyboard -> Shortcuts -> Services -> New Terminal at Folders/New T ...

  6. java 实现从15位~18位的身份证号码转换,校验中国大陆公民身份证、香港居民身份证、澳门身份证和台湾身份证。

    package xidian.sl.netcredit.util; /** * Copyright (C) 2009-2010 Yichuan, Fuchun All rights reserved. ...

  7. RSA签名验签学习笔记

    RSA私钥签名时要基于某个HASH算法,比如MD5或者SHA1等.之前我一直认为签名的过程是:先对明文做HASH计算,然后用私钥直接对HASH值加密.最近才发现不是那么简单,需要对HASH后的数据进行 ...

  8. C#微信公众号开发系列教程四(接收普通消息)

    微信公众号开发系列教程一(调试环境部署) 微信公众号开发系列教程一(调试环境部署续:vs远程调试) C#微信公众号开发系列教程二(新手接入指南) C#微信公众号开发系列教程三(消息体签名及加解密) C ...

  9. unity3d CarWaypoints插件

    编写初衷: 1.网上没有现成的好用的waypoints插件 2.自己在做一个赛车游戏,如果没有这款插件的话在制作游戏的过程中会被累成狗 3.从来没有接触过插件方面的东西,所以想自己尝试一下 插件用途: ...

  10. 用 canvas 做个好玩的网站背景

    不知不觉又好久没更过博客了,老调新弹一下,之前做的一个小效果,觉得蛮有意思的,也有朋友问是怎么做的,就分享一下,写个博文吧. 先上demo吧:http://whxaxes.github.io/canv ...