把边的编号看成边权,维护每个状态对应的最大生成树,得到一个数组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)的更多相关文章

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

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

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

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

  3. bzoj3514(LCT+主席树)

    题目描述 N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. 题解 对于一个截止时间来说,越晚的变越好. 所以我们可以维护一颗以边的序号为关键字的最大生成树,然后用主席树维 ...

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

    题解: 还是比较简单的 首先我们的思路是 确定起点 然后之后贪心的选择边(也就是越靠前越希望选) 我们发现我们只需要将起点从后向前枚举 然后用lct维护连通性 因为强制在线,所以用主席树记录状态就可以 ...

  5. BZOJ3514: Codechef MARCH14 GERALD07加强版【LCT】【主席树】【思维】

    Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密. 接下来 ...

  6. BZOJ3514:GERALD07加强版(LCT,主席树)

    Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密. 接下来 ...

  7. [bzoj3514][CodeChef GERALD07] Chef ans Graph Queries [LCT+主席树]

    题面 bzoj上的强制在线版本 思路 首先可以确定,这类联通块相关的询问问题,都可以$LCT$+可持久化记录解决 用LCT维护生成树作为算法基础 具体而言,从前往后按照边的编号顺序扫一遍边 如果这条边 ...

  8. BZOJ3514: Codechef MARCH14 GERALD07加强版(LCT,主席树)

    Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密.接下来M ...

  9. BZOJ3514 / Codechef GERALD07 Chef and Graph Queries LCT、主席树

    传送门--BZOJ 传送门--VJ 考虑使用LCT维护时间最大生成树,那么对于第\(i\)条边,其加入时可能会删去一条边.记\(pre_i\)表示删去的边的编号,如果不存在则\(pre_i = 0\) ...

随机推荐

  1. gentoo freemind 安装设置

    安装 freemind 之后,感觉菜单上面的字体比较模糊,通过设置 tools --> preference 中的 defaults --> default fonts 里面 的 defa ...

  2. Java 原子语义同步的底层实现

    原子语义同步的底层实现 volatile volatile只能保证变量对各个线程的可见性,但不能保证原子性.关于 Java语言 volatile 的使用方法就不多说了,我的建议是 除了 配合packa ...

  3. 渲染函数render和函数式组件

    vnode对象 vnode对象包括(vnode并不是vue实例,而是vue实例中渲染函数render执行后生成的结果) this.tag = tag // 当前节点标签名 this.data = da ...

  4. js方法用来获取路径传参上所带的参数

    //js方法用来获取路径传参上所带的参数 function GetQueryString(param) { var reg = new RegExp("(^|&)" + p ...

  5. 2017-11-04 Sa Oct 消参

    2017-11-04 Sa $ P(-3, 0) $ 在圆C $ (x-3)^2 + y^2 = 8^2 $ 内,动圆M与圆相切且过P点,求M点轨迹. 设切点 $ A(a, b) $,圆心 \(M(x ...

  6. (转)在T-SQL语句中访问远程数据库

    https://www.cnblogs.com/lgx5/p/7821887.html 1.启用Ad Hoc Distributed Queries 在使用openrowset/opendatasou ...

  7. js 冒泡事件 点击任意地方隐藏元素

    $(function () { $("#but").click(function (e) {// $();//显示速度 /*阻止冒泡事件*/ e = window.event || ...

  8. 在windows下安装Git并用GitHub同步

    准备环境: 1,注册github账户 2,下载安装git(下载地址:https://git-scm.com/download/win) 注释: git是什么? git是版本管理工具,当然也是分布式的管 ...

  9. C程序的编译与链接

    编译器驱动程序 编译器驱动程序可以在用户需要时调用语言预处理器.编译器.汇编器和链接器. 例如使用GNU编译系统,我们需要使用如下命令来调用GCC驱动程序: gcc -o main main.c 编译 ...

  10. MySQL经典练习题

    表名和字段 –1.学生表 Student(s_id,s_name,s_birth,s_sex) –学生编号,学生姓名, 出生年月,学生性别 –2.课程表 Course(c_id,c_name,t_id ...