题面

bzoj上的强制在线版本

思路

首先可以确定,这类联通块相关的询问问题,都可以$LCT$+可持久化记录解决

用LCT维护生成树作为算法基础

具体而言,从前往后按照边的编号顺序扫一遍边

如果这条边两端不在同一个$LCT$联通块中,则$link$

否则$cut$掉当前连接两条边的路径上的编号最小的边,并$link$

记录$ntr[i]$表示第$i$条边触发第二种情况时$link$前$cut$掉的边的编号

如果触发第一种情况,则$ntr[i]=0$

如果为自环,则$ntr[i]=i$

这样记录之后,建立$ntr[i]$的主席树,每次在$ntr[i]$的位置+1

对于查询$[l,r]$,$Ans=n-query(0,l-1,root[l-1],root[r])$

具体原因为:考虑每个$ntr$值大于等于$l$的边,显然它们在不在对答案都没有贡献(因为已经被ntr了)

否则,它们会连接两个联通块,但是这条边不在$[l,r]$区间内,所以有联通块个数-1的贡献

Code

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cstdio>
#define mp make_pair
using namespace std;
inline int read(){
int re=0,flag=1;char ch=getchar();
while(!isdigit(ch)){
if(ch=='-') flag=-1;
ch=getchar();
}
while(isdigit(ch)) re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
return re*flag;
}
int fa[400010],ch[400010][2],val[400010],minn[400010],rev[400010];
void update(int x){
minn[x]=x;
if(val[minn[x]]>val[minn[ch[x][0]]]) minn[x]=minn[ch[x][0]];
if(val[minn[x]]>val[minn[ch[x][1]]]) minn[x]=minn[ch[x][1]];
}
int nroot(int x){return ((ch[fa[x]][0]==x)||(ch[fa[x]][1]==x));}
int get(int x){return ch[fa[x]][1]==x;}
void pushrev(int x){
if(!x) return;
swap(ch[x][0],ch[x][1]);
rev[x]^=1;
}
void pushdown(int x){
if(!rev[x]) return;
pushrev(ch[x][0]);
pushrev(ch[x][1]);
rev[x]=0;
}
void push(int x){
if(!x) return;
if(nroot(x)) push(fa[x]);
pushdown(x);
}
void rotate(int x){
int f=fa[x],ff=fa[f],son=get(x),nr=nroot(f);
// cout<<" rotate "<<x<<' '<<f<<' '<<ff<<' '<<son<<' '<<ch[x][0]<<' '<<ch[x][1]<<' '<<ch[f][0]<<' '<<ch[f][1]<<'\n';
ch[f][son]=ch[x][son^1];
if(ch[f][son]) fa[ch[f][son]]=f;
fa[f]=x;ch[x][son^1]=f;
fa[x]=ff;
if(nr) ch[ff][ch[ff][1]==f]=x;
update(f);update(x);
}
void splay(int x){
// cout<<" splay "<<x<<'\n';
push(x);
for(int f;nroot(x);rotate(x)){
f=fa[x];
if(nroot(f))
rotate((get(x)==get(f))?f:x);
}
}
void access(int x){
// cout<<"access "<<x<<'\n';
for(int y=0;x;y=x,x=fa[x]){
splay(x);ch[x][1]=y;update(x);
// cout<<" do "<<x<<' '<<fa[x]<<' '<<y<<'\n';
}
}
void mroot(int x){
access(x);splay(x);pushrev(x);
}
void link(int u,int v){
mroot(u);fa[u]=v;
}
void cut(int u,int v){
mroot(u);access(v);splay(v);
fa[u]=ch[v][0]=0;
}
int find(int u){
access(u);splay(u);
while(ch[u][0]) u=ch[u][0];
return u;
}
int query(int u,int v){
mroot(u);access(v);splay(v);
return minn[v];
}
int lc[4000010],rc[4000010],seg[4000010],cnt;
int ntr[400010],root[400010];
int insert(int l,int r,int pre,int pos){
int cur=++cnt,mid=(l+r)>>1;
lc[cur]=lc[pre];rc[cur]=rc[pre];seg[cur]=seg[pre]+1;
if(l==r) return cur;
if(mid>=pos) lc[cur]=insert(l,mid,lc[pre],pos);
else rc[cur]=insert(mid+1,r,rc[pre],pos);
return cur;
}
int query(int l,int r,int ql,int qr,int pre,int cur){
if(l>=ql&&r<=qr) return seg[cur]-seg[pre];
int mid=(l+r)>>1,re=0;
if(mid>=ql) re+=query(l,mid,ql,qr,lc[pre],lc[cur]);
if(mid<qr) re+=query(mid+1,r,ql,qr,rc[pre],rc[cur]);
return re;
}
int n,m,q;
void init(){
n=read();m=read();q=read();cnt=0;
memset(lc,0,sizeof(lc));memset(rc,0,sizeof(rc));memset(seg,0,sizeof(seg));
for(int i=1;i<=n;i++) fa[i]=ch[i][0]=ch[i][1]=0,minn[i]=i,val[i]=1e9,rev[i]=0;
val[0]=1e9;
}
pair<int,int>e[200010];
int main(){
int T=read(),i,t1,t2,tmp,w;
while(T--){
init();
// cout<<n<<' '<<m<<' '<<q<<'\n';
for(i=1;i<=m;i++){
t1=read();t2=read();
e[i]=mp(t1,t2);
// cout<<"input "<<t1<<' '<<t2<<'\n';
if(t1==t2){ntr[i]=i;continue;}
if(find(t1)==find(t2)){
tmp=query(t1,t2);w=val[tmp];
ntr[i]=w;
cut(tmp,e[w].first);
cut(tmp,e[w].second);
}
else ntr[i]=0;
// cout<<"passed "<<ntr[i]<<'\n';
fa[n+i]=ch[n+i][0]=ch[n+i][1]=0;
val[n+i]=i;minn[n+i]=n+i;rev[n+i]=0;
link(n+i,t1);link(n+i,t2);
}
for(i=1;i<=m;i++) root[i]=insert(0,m,root[i-1],ntr[i]);
for(i=1;i<=q;i++){
t1=read();t2=read();
printf("%d\n",n-query(0,m,0,t1-1,root[t1-1],root[t2]));
}
}
}

[bzoj3514][CodeChef GERALD07] Chef ans Graph Queries [LCT+主席树]的更多相关文章

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

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

  2. [CodeChef - GERALD07 ] Chef and Graph Queries

    Read problems statements in Mandarin Chineseand Russian. Problem Statement Chef has a undirected gra ...

  3. 【CodeChef】Chef and Graph Queries

    Portal --> CC Chef and Graph Queries Solution 快乐数据结构题(然而好像有十分优秀的莫队+可撤销并查集搞法qwq) 首先考虑一种方式来方便一点地..计 ...

  4. [BZOJ 3514]Codechef MARCH14 GERALD07加强版 (CHEF AND GRAPH QUERIES)

    [BZOJ3514] Codechef MARCH14 GERALD07加强版 (CHEF AND GRAPH QUERIES) 题意 \(N\) 个点 \(M\) 条边的无向图,\(K\) 次询问保 ...

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

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

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

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

  7. BZOJ 3514: Codechef MARCH14 GERALD07加强版 [LCT 主席树 kruskal]

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

  8. BZOJ 3514: Codechef MARCH14 GERALD07加强版(LCT + 主席树)

    题意 \(N\) 个点 \(M\) 条边的无向图,询问保留图中编号在 \([l,r]\) 的边的时候图中的联通块个数. \(K\) 次询问强制在线. \(1\le N,M,K \le 200,000\ ...

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

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

随机推荐

  1. 关于TP3.2框架读取Sql server中文字段数据以及处理乱码的一些小心得

    最近要做一个项目,需要使用TP3.2框架,之前什么也不会,就硬着头皮上了,结果真的闹了挺多emmmmmm挺低级的错误,就像SQL Server中文字段的读取,一开始我是照着读取英文字段的格式来写的,在 ...

  2. Swoole 创建服务

    1: 创建TCP 服务器 $serv = new swoole_server(‘127.0.0.1’,9501); 2:创建UDP服务器 $serv =  new swoole_server('127 ...

  3. scrapy之分布式

    分布式爬虫 概念:多台机器上可以执行同一个爬虫程序,实现网站数据的分布爬取. 原生的scrapy是不可以实现分布式爬虫? a) 调度器无法共享 b) 管道无法共享 工具 scrapy-redis组件: ...

  4. strak组件(9):关键字搜索

    效果图: 在列表视图函数增加搜索功能. 新增函数 def get_search_list(self) 钩子方法,获取搜索条件 一.strak组件 strak/service/core_func.py ...

  5. 20145202马超《Java程序设计》第十周学习总结

    一.网络编程 1.网络概述 网络编程就是在两个或两个以上的设备(例如计算机)之间传输数据.程序员所作的事情就是把数据发送到指定的位置,或者接收到指定的数据,这个就是狭义的网络编程范畴.在发送和接收数据 ...

  6. python面向对象的反射

    python面向对象中的反射:通过字符串的形式操作对象相关的属性.python中的一切事物都是对象(都可以使用反射) getattr # 根据字符串的形式,去对象中找成员.hasattr # 根据字符 ...

  7. c语言的左移、右移

    先说左移,左移就是把一个数的所有位都向左移动若干位,在C中用<<运算符.例如: int i = 1; i = i << 2;  //把i里的值左移2位 也就是说,1的2进制是0 ...

  8. border与background定位

    1.background定位的局限 只能相对于左上角数值定位,不能相对于右下 即background-position默认相对于左上方定位的 2.怎样让图片相对于右下角? background-pos ...

  9. 剑指Offer - 九度1505 - 两个链表的第一个公共结点

    剑指Offer - 九度1505 - 两个链表的第一个公共结点2013-11-24 20:09 题目描述: 输入两个链表,找出它们的第一个公共结点. 输入: 输入可能包含多个测试样例.对于每个测试案例 ...

  10. 《Cracking the Coding Interview》——第11章:排序和搜索——题目4

    2014-03-21 21:28 题目:给定一个20GB大小的文本文件,每一行都是一个字符串.请设计方法将这个文件里的字符串排序. 解法:请看下面的注释. 代码: // 11.4 Given a fi ...