沉迷Link-Cut tree无法自拔之:[BZOJ3514] Codechef MARCH14 GERALD07 加强版
来自蒟蒻 \(Hero \_of \_Someone\) 的 \(LCT\) 学习笔记
$
$
又是一道骚题......
先讲一个结论:
假设我们用 \(LCT\) 来做这道题, 在插入边 \(i\) 的时候如果遇到了环, 则将环上最早加入的那条边删掉, 并插入边 \(i\),
记 \(cnm [i]\) 为被删除边的编号, 如果插入边 \(i\) 时没有遇到环, 则记 \(cnm[i]=0\).
那么, 每一个询问的答案即为, \(n\ -\ [l,r]中小于\ l\ 的\ cnm[i]\ 的个数\).
$
$
证明:
假设加入边 \(i\) 后形成的的环上没有 \(i\) 和 \(cnm[i]\) 这两条边, 那么这个环将变成两个连通块,
而在加入 \(i\) 且 \(cnm[i]<l\) (即在该询问中, \(cnm[i]\) 并不存在于图中)时, 这两个连通块变成了一个连通块, 即连通块数量 \(-1\) ,
所以 \([l,r]\) 中小于 \(l\) 的 \(cnm[i]\) 的个数即为减少的连通块数量, 得证.
$
$
所以这道题的做法就出来了, 用 \(LCT\) 来求 \(cnm[]\) , 主席树或者树套树维护 \([l,r]\) 中小于 \(l\) 的 \(cnm[i]\) 的个数
$
$
//made by Hero_of_Someone
#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<algorithm>
#define N (400010)
#define RG register
using namespace std;
inline int gi(){ RG int x=0,q=1; RG char ch=getchar(); while((ch<'0'||ch>'9')&&ch!='-') ch=getchar();
if(ch=='-') q=-1,ch=getchar(); while('0'<=ch&&ch<='9') x=x*10+ch-'0',ch=getchar(); return q*x; }
void File(){freopen(".in","r",stdin);freopen(".out","w",stdout);}
int n,m,k,type,cnm[N];
struct Edge{int u,v;}E[N],e[N];
//------------ lct -----------------------------
int ch[N][2],fa[N],rev[N];
int val[N],Min[N];
inline void cur(int x,int y){ val[x]=Min[x]=y; }
inline void up(int x){
Min[x]=min(Min[ch[x][0]],Min[ch[x][1]]);
Min[x]=min(Min[x],val[x]);
}
inline void reverse(int x){
if(!x) return ;
swap(ch[x][0],ch[x][1]);
rev[x]^=1;
}
inline void down(int x){
if(!rev[x]) return ;
reverse(ch[x][0]);
reverse(ch[x][1]);
rev[x]=0;
}
inline bool is_root(int x){ return ch[fa[x]][0]!=x && x!=ch[fa[x]][1]; }
inline bool lr(int x){ return x==ch[fa[x]][1]; }
inline void rotate(int x){
RG int y=fa[x],z=fa[y],k=lr(x);
if(!is_root(y)) ch[z][lr(y)]=x;
fa[x]=z; fa[ch[x][k^1]]=y; fa[y]=x;
ch[y][k]=ch[x][k^1]; ch[x][k^1]=y;
up(y); up(x);
}
int st[N];
inline void splay(int x){
RG int y=x,top=0;
while(1){
st[++top]=y;
if(is_root(y)) break;
y=fa[y];
}
for(RG int i=top;i;i--) down(st[i]);
while(!is_root(x)){
if(!is_root(fa[x])) rotate(lr(x)^lr(fa[x])?x:fa[x]);
rotate(x);
}
}
inline void access(int x){
RG int y=0;
while(x){ splay(x);
ch[x][1]=y; fa[y]=x;
up(x); y=x; x=fa[x];
}
}
inline void make_root(int x){
access(x); splay(x); reverse(x);
}
inline int query(int x,int y){
make_root(x); access(y); splay(y);
return Min[y];
}
inline int find(int x){
while(fa[x]) x=fa[x];
return x;
}
inline void link(int x,int y){
if(find(x)==find(y)) return ;
make_root(x); fa[x]=y;
}
inline void cut(int x,int y){
make_root(x); access(y); splay(y);
if(ch[y][0]==x) y=0,fa[x]=0,up(y);
}
inline void Insert(int id){
RG int x=e[id].u,y=e[id].v;
if(x==y){ cnm[id]=m+1; return ; }
if(find(x)==find(y)){
RG int tmp=query(x,y);
cnm[id]=tmp;
cut(e[tmp].u,n+tmp);
cut(e[tmp].v,n+tmp);
}
cur(n+id,id);
link(x,n+id);
link(y,n+id);
}
inline void init(){
n=gi(),m=gi(),k=gi(),type=gi();
for(RG int i=0;i<=n;i++) cur(i,m+1);
for(RG int i=1;i<=m;i++){
e[i].u=gi(),e[i].v=gi();
Insert(i);
}
}
//------------ 主席树 --------------------------
int ans,cnt,A[N];
int sz,rt[N],sum[N*20];
int ls[N*20],rs[N*20];
inline void build(int& x,int y,int l,int r,int v){
x=++sz;
if(l==r){ sum[x]=sum[y]+1; return ; }
RG int mid=(l+r)>>1;
if(v<=A[mid]){ rs[x]=rs[y];
build(ls[x],ls[y],l,mid,v);
}
else{ ls[x]=ls[y];
build(rs[x],rs[y],mid+1,r,v);
}
sum[x]=sum[ls[x]]+sum[rs[x]];
}
inline int query(int x,int y,int l,int r,int v){
if(l==r){ return A[l]<=v?sum[x]-sum[y]:0; }
RG int mid=(l+r)>>1,ret=sum[ls[x]]-sum[ls[y]];
if(v<=A[mid]) return query(ls[x],ls[y],l,mid,v);
else return query(rs[x],rs[y],mid+1,r,v)+ret;
}
//----------------------------------------------
inline void work(){
for(RG int i=1;i<=m;i++) A[i]=cnm[i];
sort(A+1,A+m+1); A[0]=-1;
for(RG int i=1;i<=m;i++)
if(A[i]!=A[cnt]) A[++cnt]=A[i];
if(A[cnt]<m+1) A[++cnt]=m+1;
for(RG int i=1;i<=m;i++)
build(rt[i],rt[i-1],1,cnt,cnm[i]);
while(k--){
RG int l=gi(),r=gi();
if(type) l^=ans,r^=ans;
ans=n-query(rt[r],rt[l-1],1,cnt,l-1);
printf("%d\n",ans);
}
}
int main(){ init(); work(); return 0; }
沉迷Link-Cut tree无法自拔之:[BZOJ3514] Codechef MARCH14 GERALD07 加强版的更多相关文章
- 【LCT+主席树】BZOJ3514 Codechef MARCH14 GERALD07加强版
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 2023 Solved: 778 ...
- [BZOJ3514]CodeChef MARCH14 GERALD07加强版(LCT+主席树)
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 2177 Solved: 834 ...
- bzoj3514 Codechef MARCH14 GERALD07加强版 lct预处理+主席树
Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 1951 Solved: 746[Submi ...
- BZOJ3514 : Codechef MARCH14 GERALD07加强版
以边编号为权值 用Link-cut Tree维护最大生成树 对于新加的第i条边(u,v) a[i]表示当a[i]这条边加入后连通块个数会减少 若u==v则a[i]=m 若u与v不连通则连上,a[i]= ...
- BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ3514 题意概括 N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. N ...
- BZOJ3514: Codechef MARCH14 GERALD07加强版【LCT】【主席树】【思维】
Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密. 接下来 ...
- BZOJ3514: Codechef MARCH14 GERALD07加强版(LCT,主席树)
Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密.接下来M ...
- BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT+可持久化线段树
自己独自想出来并切掉还是很开心的~ Code: #include <bits/stdc++.h> #define N 400005 #define inf 1000000000 #defi ...
- BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT维护最大生成树 主席树
题面 考虑没有询问,直接给你一个图问联通块怎么做. 并查集是吧. 现在想要动态地做,那么应该要用LCT. 考虑新加进来一条边,想要让它能够减少一个联通块的条件就是现在边的两个端点还没有联通. 如果联通 ...
随机推荐
- Angularjs演示Service功能
在angularjs中,我们可以自定义自己的service.可以说得是自定义的方法,函数. 下面我们一步一步来演示吧:首先为angularjs定义一个app: var demoApp = angula ...
- MySql 数据库移植记录
在使用长文本时,SqlServer 在以下情况下工作正常 [Property("CContent", ColumnType = "StringClob", Le ...
- C# LINQ 详解 From Where Select Group Into OrderBy Let Join
目录 1. 概述 2. from子句 3. where子句 4. select子句 5. group子句 6. into子句 7. 排序子句 8. let子句 9. join子句 10. 小结 1. ...
- 【IDEA】Intellij IDEA创建的Web项目配置Tomcat并启动Maven项目
转载请注明出处:http://blog.csdn.net/qq_26525215本文源自[大学之旅_谙忆的博客] 本篇博客讲解IDEA如何配置Tomcat. 大部分是直接上图哦. 点击如图所示的地方, ...
- Ubuntu16.04下安装QQ的完整操作记录(经验证可用)
本机安装了Ubuntu16.04系统,用于日常运维办公.打算在Ubuntu上安装QQ,如下操作记录也使用于Ubuntu18.04: 1)先下载特制的QQ程序包(其实就是基于Wine容器做了一些封装,程 ...
- 分页查询信息(使用jdbc连接mysql数据库实现分页查询任务)
分页查询信息 使用jdbc连接mysql数据库实现分页查询任务 通过mysql数据库提供的分页机制,实现商品信息的分页查询功能,将查询到的信息显示到jsp页面上. 本项目 ...
- Can't find model 'en'
在使用 nlp = spacy.load("en") 报错OSError: Can't find model 'en' 应该用 python -m spacy download e ...
- github链接
github链接:https://github.com/bjing123 test1:https://github.com/bjing123/test-/blob/master/test1.t ...
- 转【c语言】两个堆栈组成一个队列
假设有两个堆栈,分别是s1,s2,现在有数列“1,2,3,4,5”,要让这个数列实现先进先出的功能,也就是用两个堆栈组成一个队列,如何实现? 分析: 先将数列压入栈s1,数列在栈中由顶到底的元素为“5 ...
- shell脚本--权限分配
因为shell脚本内部是很多命令的集合,这些命令也许会涉及到操作某一个文件,而且shell脚本的运行,也是需要当前用户对脚本具有运行的权限,否则,会因为权限不够而失败. 首先最重要的一点:修改权限,只 ...