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\) ...
随机推荐
- 8-安装Kafka
1.解压 tar -zxvf kafka_2.11-0.9.0.1.tar -C /opt/app/ 2.改权限 chown -R hadoop:hadoop /opt/app/ 3.修改配置文件 c ...
- java并发编程目录
java并发编程目录 Java多线程基础:进程和线程之由来 JAVA多线程实现的四种方式 Java并发编程:线程间协作的两种方式:wait.notify.notifyAll和Condition Jav ...
- 60.纯 CSS 创作一块乐高积木
原文地址:https://segmentfault.com/a/1190000015369542 感想:y轴旋转,相对定位,今天有点懵呀,唉. HTML code: <!-- 定义dom,容器中 ...
- <记录> PHP监控进程状态,完成掉线自动重启
1. 利用Shell脚本实现 #!/bin/bash PORT= while [ true ];do read -p "please enter the port that you want ...
- 纯Java——简易高并发框架
转自:https://blog.csdn.net/MonkeyDCoding/article/details/81369610 0.源代码github-简易高并发框架 注:本篇博客知识来自于网课. 1 ...
- SQLite在Android程序中的使用方法,SQLite的增删查改方法
Sqlite: 1.一款用来实现本地数据存储的轻量级数据管理工具,是众多用来实现数据库管理的工具之一. 2.Android已经将SQLite的代码功能吸收在它的系统中,我们可以直接在Android程序 ...
- Java线程池ThreadPoolExecutor
线程池的好处 1. 降低资源的消耗 通过重复利用已创建的线程降低线程创建和销毁所造成的消耗 2. 提高响应速度 当任务到达时,任务可以不需要等到线程创建就能立即执行 3. 提高线程的可管理型 线程是稀 ...
- java.io.Flushable 接口
package java.io; import java.io.IOException; /** * 在什么情况下用呢? 缓冲输出到一个流中的情况下,这个流要刷新. */ public interfa ...
- opencv setTo()
转载至 作者:跬步达千里 opencv的setTo函数是将图像设置为某个值; 例如: 1.有一个Mat src,想将他的值全部设置成0,则可以src.setTo(0) 2.setTo还有更为高级的用法 ...
- vue 关键词模糊查询
页面html,绑定的列表数据为datas,关键词为 select_words,如下图 其中d.accounts和d.roleName是需要进行搜索的字段,也可以进行大小写都可以