把边的编号看成边权,维护每个状态对应的最大生成树,得到一个数组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. k8s学习笔记之四:资源清单定义入门

    第一章.k8s中的资源 1.什么叫资源? k8s中所有的内容都抽象为资源, 资源实例化之后,叫做对象 2.在k8s中有哪些资源? 工作负载型资源(workload): Pod ReplicaSet D ...

  2. Postgres——pgadmin复制无主键单表至本地数据库

    数据库中存在无主键单表gongan_address_all ,需要将余杭区数据导出成另外一张表,因为数据量太大,sql语句效率太差. 通过sql语句查询出余杭区数据,并导出成csv,sql等格式,再导 ...

  3. hadoop的hdfs中的javaAPI操作

    package cn.itcast.bigdata.hdfs; import java.net.URI; import java.util.Iterator; import java.util.Map ...

  4. Java 中 Gson的使用

    JSON 是一种文本形式的数据交换格式,它比XML更轻量.比二进制容易阅读和编写,调式也更加方便;解析和生成的方式很多,Java中最常用的类库有:JSON-Java.Gson.Jackson.Fast ...

  5. Thrift 的五种工作模式

    一.thrift 共有5中工作模式,分成阻塞和非阻塞: 阻塞:TSimpleServer.TThreadPoolServer 非阻塞:TNonblockingServer.THsHaServer.TT ...

  6. leetcode72

    class Solution { private: ][]; public: int minDistance(string word1, string word2) { int len1 = word ...

  7. django-celery使用

    1.新进一个django项目 - proj/ - proj/__init__.py - proj/settings.py - proj/urls.py - manage.py 2.在该项目创建一个pr ...

  8. 1、python环境安装及软件介绍

    软件: python3.0 下载地址:https://www.python.org/downloads/windows/ pycharm 下载地址: https://www.jetbrains.com ...

  9. 二十一、proxyDesign 代理模式

    原理: 时序图: 代码清单: Printable public interface Printable { void setPrinterName(String name); String getPr ...

  10. 封装的mybatis连接类

    package com.kevin.utils;import org.apache.ibatis.io.Resources;import org.apache.ibatis.session.SqlSe ...