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 ...
随机推荐
- 夺命雷公狗---node.js---8url模块和util模块
我们先到手册上看看: 上面很明显就写着返回一个对象. 再来看看util模块, 废话不哦多说,先上一点代码: /** * Created by leigood on 2016/8/13. */ var ...
- 夺命雷公狗---微信开发53----网页授权(oauth2.0)获取用户基本信息接口(3)实现世界留言版
前面两节课我们讲的是base型的授权了,那么现在我们开始Userinfo型授权, 先来看下我们的原理图 我们这节课来做一个 世界留言版 系统 1..首先我还是在微信测试平台那里设置好回调页面的域名 2 ...
- Fatal error: Call to a member function bind_param() on a non-object in
今天在练习 mysql是出现错误: Fatal error: Call to a member function bind_param() on a non-object in 解决步骤: 1. ...
- 《zw版·Halcon-delphi系列原创教程》 水果自动分类脚本(机器学习、人工智能)
<zw版·Halcon-delphi系列原创教程> 水果自动分类脚本(机器学习.人工智能) 前面介绍了超市,流水线,酸奶的自动分类算法,下面再介绍一个水果的自动分类算法. Halcon强大 ...
- Sql Server Analysis Service 转换为UnknownMember的正确设置
在SSAS中事实表数据被归类到为UnknownMember 的时候分为两种情况: 第一种情况,在SSAS里面事实表中的外键是null,这种情况SSAS在建事实表和维度时ErrorConfigurati ...
- 【转载】Perl异常处理方法总结
程序脚本在运行过程中,总会碰到这样那样的问题,我们会预知一些问题并为其准备好处理代码,而有一些不能预知.好的程序要能尽可能多的处理可能出现的异常问题,本文就总结了一些方法来解决这些异常,当然perl在 ...
- 【Pro ASP.NET MVC 3 Framework】.学习笔记.3.MVC的主要工具-单元测试
IProductRepository接口定义了一个仓库,我们通过它获得.更新Product对象.IPriceReducer接口指定了一个功能,它将要对所有的Products实施,通过一个参数,降低他们 ...
- WPF:窗体置顶
1.设置窗体TopMost属性 private DispatcherTimer timer; public Window1() { InitializeComponent(); Loaded += n ...
- js作用域链与this
this的绑定与function和对象的定义位置无关,是由函数调用时的执行环境所决定的. scope chain是由函数定义时的位置决定的与函数调用时的执行环境无关.
- php变量内存完全释放
<?php echo memory_get_usage().PHP_EOL;$a = 1;$b = $a;$a = null;$b = null;unset($a);unset($b);echo ...