BZOJ 3514 Codechef MARCH14 GERALD07加强版
题目链接:http://www.lydsy.com:808/JudgeOnline/problem.php?id=3514
题意:给出一个图m条边。每次询问只加入编号在区间[L,R]之内的边有多少连通块。在线。
思路:求出[1,i]边加入时的最大生成树,即加入在[1,i]中不在生成树上的边时连通块不变。假如是离线,那么我们按照询问右端点排序,每次维护区间[L,R]中在生成树上的边即可。
现在是在线,我们用可持久化线段树维护。直观想,每次加入一条边时连通块数减少1。但是加入边R时存在环的时候这个就不满足了。设这个环上编号最小的边的编号为x,那么x一旦加入,即L<=x<R时,那么加入R时连通块数就不会再减少。因此我们在函数式线段树中的[L,R]查找区间[0,L-1]的和即可。
struct node
{
int Min,val,isReversed;
node *c[2],*f;
inline void reverse()
{
isReversed^=1;
swap(c[0],c[1]);
}
};
node a[N<<1],*nullNode;
inline void pushUp(node *p)
{
if(p==nullNode) return;
p->Min=p->val;
if(p->c[0]!=nullNode) p->Min=min(p->Min,p->c[0]->Min);
if(p->c[1]!=nullNode) p->Min=min(p->Min,p->c[1]->Min);
}
inline void pushDown(node *p)
{
if(p->isReversed)
{
if(p->c[0]!=nullNode) p->c[0]->reverse();
if(p->c[1]!=nullNode) p->c[1]->reverse();
p->isReversed=0;
}
}
inline void rotate(node *p,int k)
{
node *q=p->f;
q->c[k]=p->c[!k];
if(p->c[!k]!=nullNode) p->c[!k]->f=q;
p->c[!k]=q;
p->f=q->f;
if(q->f!=nullNode)
{
if(p->f->c[0]==q) p->f->c[0]=p;
if(p->f->c[1]==q) p->f->c[1]=p;
}
q->f=p;
pushUp(q);
}
inline int isRoot(node *p)
{
return p->f==nullNode||p->f->c[0]!=p&&p->f->c[1]!=p;
}
void splay(node *p)
{
pushDown(p);
while (!isRoot(p))
{
if(isRoot(p->f))
{
pushDown(p->f);
pushDown(p);
if(p==p->f->c[0]) rotate(p,0);
else rotate(p,1);
}
else
{
pushDown(p->f->f);
pushDown(p->f);
pushDown(p);
if(p->f->f->c[0]==p->f)
{
if(p->f->c[0]==p) rotate(p->f,0);
else rotate(p,1);
rotate(p,0);
}
else
{
if(p->f->c[1]==p) rotate(p->f,1);
else rotate(p,0);
rotate(p,1);
}
}
}
pushUp(p);
}
node* access(node *p)
{
node *q=nullNode;
while(p!=nullNode)
{
splay(p);
p->c[1]=q;
pushUp(p);
q=p;
p=p->f;
}
return q;
}
int connected(int x,int y)
{
access(a+y);
node *p=a+x;
while(p!=nullNode)
{
splay(p);
if(p->f==nullNode) break;
p=p->f;
}
while(p->c[1]!=nullNode) p=p->c[1];
return p==a+y;
}
void join(int x,int y)
{
access(a+x);
splay(a+x);
a[x].reverse();
a[x].f=a+y;
}
void cut(int x,int y)
{
access(a+x);splay(a+y);
if(a[y].f==a+x) a[y].f=nullNode;
else
{
access(a+y);
splay(a+x);
a[x].f=nullNode;
}
}
int query(int x,int y)
{
access(a+x);
node *p=a+y;
node *q=nullNode;
for(;p!=nullNode;p=p->f)
{
splay(p);
if(p->f==nullNode)
{
int ans=p->val;
if(q!=nullNode) ans=min(ans,q->Min);
if(p->c[1]!=nullNode) ans=min(ans,p->c[1]->Min);
return ans;
}
p->c[1]=q;
q=p;
pushUp(q);
}
}
int n,m,Q;
struct segNode
{
int L,R,sum;
};
segNode A[N*20];
int e;
int root[N<<1];
int add(int t,int L,int R,int p)
{
int x=++e;
if(L==R)
{
A[x].sum=A[t].sum+1;
return x;
}
A[x].L=A[t].L;
A[x].R=A[t].R;
int M=(L+R)>>1;
if(p<=M) A[x].L=add(A[t].L,L,M,p);
else A[x].R=add(A[t].R,M+1,R,p);
A[x].sum=A[A[x].L].sum+A[A[x].R].sum;
return x;
}
int type;
int edge[N][2];
void init()
{
nullNode=new node();
nullNode->isReversed=0;
nullNode->Min=INF;
nullNode->val=INF;
nullNode->c[0]=nullNode->c[1]=nullNode->f=nullNode;
n=getInt();
m=getInt();
Q=getInt();
type=getInt();
int i;
for(i=1;i<=n+m;i++)
{
if(i<=n) a[i].val=a[i].Min=INF;
else a[i].val=a[i].Min=i-n;
a[i].c[0]=a[i].c[1]=a[i].f=nullNode;
}
for(i=1;i<=m;i++) scanf("%d%d",&edge[i][0],&edge[i][1]);
for(i=1;i<=m;i++)
{
int u=edge[i][0];
int v=edge[i][1];
if(u==v)
{
root[i]=root[i-1];
continue;
}
if(connected(u,v))
{
int t=query(u,v);
cut(n+t,edge[t][0]);
cut(n+t,edge[t][1]);
root[i]=add(root[i-1],0,m,t);
join(i+n,u);
join(i+n,v);
}
else
{
root[i]=add(root[i-1],0,m,0);
join(i+n,u);
join(i+n,v);
}
}
}
int query(int x,int y,int L,int R,int ll,int rr)
{
if(L==ll&&R==rr) return A[x].sum-A[y].sum;
int M=(L+R)>>1;
if(rr<=M) return query(A[x].L,A[y].L,L,M,ll,rr);
if(ll>M) return query(A[x].R,A[y].R,M+1,R,ll,rr);
int ans=query(A[x].L,A[y].L,L,M,ll,M);
ans+=query(A[x].R,A[y].R,M+1,R,M+1,rr);
return ans;
}
int main()
{
init();
int ans=0;
while(Q--)
{
int L=getInt();
int R=getInt();
if(type) L^=ans,R^=ans;
ans=n-query(root[R],root[L-1],0,m,0,L-1);
printf("%d\n",ans);
}
}
BZOJ 3514 Codechef MARCH14 GERALD07加强版的更多相关文章
- BZOJ 3514: Codechef MARCH14 GERALD07加强版( LCT + 主席树 )
从左到右加边, 假如+的边e形成环, 那么记下这个环上最早加入的边_e, 当且仅当询问区间的左端点> _e加入的时间, e对答案有贡献(脑补一下). 然后一开始是N个连通块, 假如有x条边有贡献 ...
- 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加强版 (CHEF AND GRAPH QUERIES)
[BZOJ3514] Codechef MARCH14 GERALD07加强版 (CHEF AND GRAPH QUERIES) 题意 \(N\) 个点 \(M\) 条边的无向图,\(K\) 次询问保 ...
- BZOJ 3514: Codechef MARCH14 GERALD07加强版(LCT + 主席树)
题意 \(N\) 个点 \(M\) 条边的无向图,询问保留图中编号在 \([l,r]\) 的边的时候图中的联通块个数. \(K\) 次询问强制在线. \(1\le N,M,K \le 200,000\ ...
- 【刷题】BZOJ 3514 Codechef MARCH14 GERALD07加强版
Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密. 接下来 ...
- BZOJ 3514 Codechef MARCH14 GERALD07加强版 Link-Cut-Tree+划分树
题目大意: 给定n个点m条边的无向图.求问当图中仅仅有[编号在[l,r]区间内]的边存在时图中的联通块个数 强制在线 注意联通块是指联通了就是同一块,不是Tarjan求的那种块 看到这题的那一刻我就想 ...
- BZOJ 3514: Codechef MARCH14 GERALD07加强版 (LCT维护最大生成树+主席树)
题意 给出nnn个点,mmm条边.多次询问,求编号在[l,r][l,r][l,r]内的边形成的联通块的数量,强制在线. 分析 LCTLCTLCT维护动态最大生成树,先将每条边依次加进去,若形成环就断掉 ...
- 【BZOJ-3514】Codechef MARCH14 GERALD07加强版 LinkCutTree + 主席树
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 1288 Solved: 490 ...
- 【LCT+主席树】BZOJ3514 Codechef MARCH14 GERALD07加强版
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 2023 Solved: 778 ...
随机推荐
- zw版【转发·台湾nvp系列Delphi例程】HALCON EdgesImage
zw版[转发·台湾nvp系列Delphi例程]HALCON EdgesImage procedure TForm1.Button1Click(Sender: TObject);var img0, im ...
- 【转】The Attached Behavior Pattern
原文:http://www.bjoernrochel.de/2009/08/19/the-attached-behavior-pattern/ The Attached Behavior Patter ...
- 使用JWPlayer在网页中嵌入视频
首发:个人博客,持续更新和纠错 我一直以为在网页中嵌入视频是件复杂的事,一研究才知道原来非常简单. 实际就是在页面中嵌入个控件.社区里已有很多解决方案了.jwplayer是最受欢迎的(之一).控件包括 ...
- Ul li 竖排 菜单
Ul li 竖排 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://ww ...
- 160922、配置:spring通过profile或@profile配置不同的环境(测试、开发、生产)
一.配置环境 applicationContext.xml中添加下边的内容(develop:开发环境,production:生产环境,test:测试环境) 注意:profile的定义一定要在文档的最下 ...
- 坑爹的SQL ISNUMERIC
select ISNUMERIC('01,02') ISNUMERIC返回 1,后面用patindex代替了...折腾/ select patindex('%[^0-9]%','01,02')
- How To Create a SSL Certificate on Apache for CentOS 6
About Self-Signed Certificates 自签证书.一个SSL证书,是加密网站的信息,并创建更安全的链接的一种方式.附加地,证书可以给网站浏览者显示VPS的的身份证明信息.如果一个 ...
- 微信清理H5真的太早了?这会是应用号发布的前兆吗
三少爷的剑 2016-04-18 21:05 收藏35 评论7 两天之内,整个 H5 游戏创业陷入了两年狂热期以来最冷的冰点. 每一个正在忙于 H5 小游戏开发的开发者都在忙于砍掉游戏代码中有关 ...
- 一道面试题比较synchronized和读写锁
一.科普定义 这篇博文的两个主角“synchronized”和“读写锁” 1)synchronized 这个同步关键字相信大家都用得比较多,在上一篇“多个线程之间共享数据的方式”中也详细列举他的应用, ...
- 使用Window Live Writer写博客
1.打开“日志账户”—>“日志选项”. 2.点击“更新账户信息”. 3.输入博客地址,用户名和密码,点击“下一步”. 4.耐心等待片刻... 5.设置“日志昵称”,点击“完成”. 这样就大功告成 ...