bzoj3514(主席树+lct)
把边的编号看成边权,维护每个状态对应的最大生成树,得到一个数组a[i],表示第i条边在这个过程中替换的是那条边,询问时看一下a[l,r]内啊有多少个小于l的算一下答案就好;代码参考:http://blog.csdn.net/thy_asdf/article/details/50518526
//lct不好处理边权,把一条边转成夹在两个点之间的点;
#include<iostream>
#include<cstring>
#include<cmath>
#include<cstdio>
#include<algorithm>
using namespace std;
const int maxn=,maxt=,inf=1e9;
struct edg{
int u,v;
}e[maxn];
struct node{
int l,r,v;
}tr[maxt];
int n,m,k,tot,root[maxn],a[maxn],type,lastans;
void insert(int t,int l,int r,int &x){
++tot;tr[tot]=tr[x];x=tot;
++tr[tot].v;
if(l==r)return;
int mid=l+r>>;
if(t<=mid)insert(t,l,mid,tr[x].l);
else insert(t,mid+,r,tr[x].r);
}
int qs(int x,int y,int l,int r,int L,int R){
if(r<L||l>R||l>r)return ;
if(l>=L&&r<=R)return tr[y].v-tr[x].v;
int mid=l+r>>;
return qs(tr[x].l,tr[y].l,l,mid,L,R)+qs(tr[x].r,tr[y].r,mid+,r,L,R);
}
struct node2{
int ls,rs,fa,is_root;
}tre[maxn];
int siz[maxn],mins[maxn],val[maxn],cnt,rev[maxn];
void update(int x){
mins[x]=x;
if(val[mins[tre[x].ls]]<val[mins[x]])mins[x]=mins[tre[x].ls];
if(val[mins[tre[x].rs]]<val[mins[x]])mins[x]=mins[tre[x].rs];
}
void flip(int x){swap(tre[x].ls,tre[x].rs);rev[x]^=;}
void pushdown(int x){if(rev[x])flip(tre[x].ls),flip(tre[x].rs),rev[x]^=;}
void relax(int x){if(tre[x].fa)relax(tre[x].fa);pushdown(x);}
void rx(int x){
int y=tre[x].fa,z=tre[y].fa;
tre[y].ls=tre[x].rs;
if(tre[x].rs)tre[tre[x].rs].fa=y;
tre[x].rs=y;tre[y].fa=x;
tre[x].fa=z;
if(z&&!tre[y].is_root){
if(tre[z].ls==y)tre[z].ls=x;else tre[z].rs=x;
}
if(tre[y].is_root)tre[x].is_root=,tre[y].is_root=;
update(y);update(x);
}
void lx(int x){
int y=tre[x].fa,z=tre[y].fa;
tre[y].rs=tre[x].ls;
if(tre[x].ls)tre[tre[x].ls].fa=y;
tre[x].ls=y;tre[y].fa=x;
tre[x].fa=z;
if(z&&!tre[y].is_root){
if(tre[z].ls==y)tre[z].ls=x;else tre[z].rs=x;
}
if(tre[y].is_root)tre[x].is_root=,tre[y].is_root=;
update(y);update(x);
}
void splay(int x){
relax(x);
while(!tre[x].is_root){
//cout<<"orz"<<endl;
int y=tre[x].fa,z=tre[y].fa;
if(tre[y].is_root){if(tre[y].ls==x)rx(x);else lx(x);}
else{
if(tre[z].ls==y&&tre[y].ls==x){rx(y);rx(x);}
else if(tre[z].ls==y&&tre[y].rs==x){lx(x);rx(x);}
else if(tre[z].rs==y&&tre[y].ls==x){rx(x);lx(x);}
else {lx(y);lx(x);}
}
}
}
void ace(int x){
int y=;
do{
splay(x);
if(tre[x].rs)tre[tre[x].rs].is_root=;
tre[tre[x].rs=y].is_root=;
update(x);
x=tre[y=x].fa;
}while(x);
}
void makeroot(int x){ace(x);splay(x);flip(x);}
void link(int x,int y){makeroot(x);tre[x].fa=y;}
void cut(int x,int y){makeroot(x);ace(y);splay(y);tre[y].ls=tre[x].fa=;tre[x].is_root=;}//一开始最后这句话丢了;
int findrt(int x){ace(x);splay(x);for(;tre[x].ls;x=tre[x].ls);return x;}
int query(int x,int y){makeroot(x);ace(y);splay(y);return mins[y];}
void pre(){
for(int i=;i<=n+m;++i)tre[i].is_root=;
cnt=n;
for(int i=;i<=m;++i){
int u=e[i].u,v=e[i].v;
if(u==v){a[i]=i;continue;}
if(findrt(u)==findrt(v)){
int cp=query(u,v),x=val[cp];
a[i]=x;cut(e[x].u,cp);cut(e[x].v,cp);
}
++cnt;mins[cnt]=cnt;val[cnt]=i;link(u,cnt);link(v,cnt);
}
for(int i=;i<=m;++i){
root[i]=root[i-];insert(a[i],,m,root[i]);
}
}
int main(){
cin>>n>>m>>k>>type;
val[]=inf;
for(int i=;i<=n;++i)mins[i]=i,val[i]=inf;
for(int i=;i<=m;++i)scanf("%d%d",&e[i].u,&e[i].v);
pre();
int l,r;
for(int i=;i<=k;++i){
scanf("%d%d",&l,&r);
if(type)l^=lastans,r^=lastans;
printf("%d\n",lastans=(n-qs(root[l-],root[r],,m,,l-)));
}
return ;
}
bzoj3514(主席树+lct)的更多相关文章
- BZOJ_3514_Codechef MARCH14 GERALD07加强版_主席树+LCT
BZOJ_3514_Codechef MARCH14 GERALD07加强版_主席树+LCT Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. I ...
- [BZOJ3514]CodeChef MARCH14 GERALD07加强版(LCT+主席树)
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 2177 Solved: 834 ...
- bzoj3514(LCT+主席树)
题目描述 N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. 题解 对于一个截止时间来说,越晚的变越好. 所以我们可以维护一颗以边的序号为关键字的最大生成树,然后用主席树维 ...
- 【BZOJ3514】Codechef MARCH14 GERALD07加强版 LCT+主席树
题解: 还是比较简单的 首先我们的思路是 确定起点 然后之后贪心的选择边(也就是越靠前越希望选) 我们发现我们只需要将起点从后向前枚举 然后用lct维护连通性 因为强制在线,所以用主席树记录状态就可以 ...
- BZOJ3514: Codechef MARCH14 GERALD07加强版【LCT】【主席树】【思维】
Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密. 接下来 ...
- BZOJ3514:GERALD07加强版(LCT,主席树)
Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密. 接下来 ...
- [bzoj3514][CodeChef GERALD07] Chef ans Graph Queries [LCT+主席树]
题面 bzoj上的强制在线版本 思路 首先可以确定,这类联通块相关的询问问题,都可以$LCT$+可持久化记录解决 用LCT维护生成树作为算法基础 具体而言,从前往后按照边的编号顺序扫一遍边 如果这条边 ...
- BZOJ3514: Codechef MARCH14 GERALD07加强版(LCT,主席树)
Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密.接下来M ...
- BZOJ3514 / Codechef GERALD07 Chef and Graph Queries LCT、主席树
传送门--BZOJ 传送门--VJ 考虑使用LCT维护时间最大生成树,那么对于第\(i\)条边,其加入时可能会删去一条边.记\(pre_i\)表示删去的边的编号,如果不存在则\(pre_i = 0\) ...
随机推荐
- DeepLearning初窥门径
说明: 最近在看Ng的DL课程,感觉说的非常好,浅显易懂! 本来打算记录一下自己的学习过程,网上几个大神总结的太完美了,根本没必要自己去写了,而且浪费时间~~ 网易地址:http://mooc.stu ...
- ubuntu 16.04 安装中文语言包
安装中文语言包 sudo apt-get install language-pack-zh-han* 安装gnome包 sudo apt-get install language-pack-gn ...
- !!!常用SVG代码
http://www.w3school.com.cn/svg/svg_examples.asp svg实例 http://www.w3school.com.cn/svg/svg_reference.a ...
- ZIP压缩输入/输出流
ZIP是压缩文件的格式,使用ZIP可以节省空间 java将压缩/解压缩文件的方法都封装在java.util.zip包下,java实现了I/O数据流和网络数据流的单一接口,所以实现起来比较容易. 主要的 ...
- setTimeout应用例子-移入移出div显示和隐藏
效果:移入div1,div2保持显示,移出div1,div2消失. 移入div2,div2保持显示,移出div2,div2消失. 一.HTML代码 <div id='div1'></ ...
- nexus的安装和简介(3)
从私服下载jar包 没有配置nexus之前,如果本地仓库没有,去中央仓库下载,通常在企业中会在局域网内部署一台私服服务器,有了私服本地项目首先去本地仓库找jar,如果没有找到则连接私服从私服下载ja ...
- Java ArrayList调用构造方法传入"容量size"不生效,如何初始化List容量size
创建一个ArrayList对象,传入整型参数 @Test public void arrayListConstructor(){ ArrayList<Object> objects = n ...
- 微信公众号Java接入demo
微信公众号Java接入demo 前不久买了一台服务,本来是用来当梯子用的,后来买了一个域名搭了一个博客网站,后来不怎么在上面写博客一直闲着,最近申请了一个微信公众号就想着弄点什么玩玩.周末没事就鼓捣了 ...
- python虚拟环境的搭建
使用python虚拟环境作用是项目与项目之间相互隔离,互相不受影响,比如当需要同时部署A.B两个项目时,A项目依赖C库的1.0版本,B项目依赖C库的2.0版本,假如不使用虚拟环境隔离A项目和B项目就很 ...
- FortiGate防火墙HA下联堆叠交换机
1.拓扑图 2.防火墙配置 3.交换机配置 interface GigabitEthernet1/0/47 switchport access vlan 30 switchport mode acce ...