GERALD07加强版:lct,主席树,边化点
Description:N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数。
传送门。
lct这么神仙的东西一个题解都不写怎么行???
神仙思路啊。
其实不是很难但是的确不容易想到。
我们考虑答案是什么。
首先刚开始有n个点分别是联通块,然后你连了一些边使联通块减少了。
怎么减少的呢?就是区间的边的生成树上边的数量。因为如果不是生成树上的边,那么一定与生成树上的边成环了而不会合并联通块。
怎么判断边是不是区间内生成树上的边呢?判断依据就是它有没有和前面的边成环。
那么我们先把边连起来,当连边时我们发现这两个点已经联通时,这条边就可以取代出现的最早的那条边。
如果它取代的那条边不在区间之内,那么这条边就在生成树上。
所以就来一棵LCT,边化点后维护最大编号就行,把每条边插入之前询问会被替代的边,存在数组lst里。
那么对于每一组询问,问题就变成了问在数组lst下标[l,r]内lst值小于l的有几个。
用主席树维护一下就好了。
记住这种思路。
#include<cstdio>
#include<iostream>
using namespace std;
int c[][],f[],w[],n,m,k,opt,fid[],lst[],q[];
int x[],y[],ans,rt[],v[],t[][],lz[],cnt;
int find(int p){return fid[p]==p?p:fid[p]=find(fid[p]);}
#define lc c[p][0]
#define rc c[p][1]
bool not_root(int p){return c[f[p]][]==p||c[f[p]][]==p;}
void rev(int p){lc^=rc^=lc^=rc;lz[p]^=;}
void down(int p){if(lz[p])rev(lc),rev(rc),lz[p]=;}
void up(int p){w[p]=min(p>n?p:,min(w[lc],w[rc]));}
void rotate(int p){
int fa=f[p],gr=f[fa],dir=c[fa][]==p,br=c[p][!dir];
if(not_root(fa))c[gr][c[gr][]==fa]=p; c[p][!dir]=fa; c[fa][dir]=br;
f[p]=gr; f[fa]=p; f[br]=fa; up(fa);
}
void splay(int p){
int res=p,top=;q[++top]=p;
while(not_root(res))q[++top]=res=f[res];
while(top)down(q[top--]);
while(not_root(p)){
int fa=f[p],gr=f[fa];
if(not_root(fa))rotate(c[fa][]==p^c[gr][]==fa?fa:p);
rotate(p);
}
up(p);
}
void access(int p){for(int y=;p;p=f[y=p])splay(p),rc=y,up(p);}
void make_root(int p){access(p);splay(p);rev(p);}
void split(int x,int y){make_root(x);access(y);splay(y);}
void cut(int x,int y){split(x,y);f[x]=c[y][]=;up(y);}
void link(int x,int y){make_root(x);f[x]=y;up(y);}
void build(int &p,int cpy,int adx,int l=,int r=m){
if(!p)p=++cnt;
if(l==r){v[p]=v[cpy]+;return;}
if(adx<=l+r>>)build(t[p][],t[cpy][],adx,l,l+r>>),t[p][]=t[cpy][];
else build(t[p][],t[cpy][],adx,(l+r>>)+,r),t[p][]=t[cpy][];
v[p]=v[t[p][]]+v[t[p][]];//printf("%d %d %d\n",l,r,v[p]);
}
int ask(int p1,int p2,int l,int r,int cl=,int cr=m){//printf("%d %d %d %d\n",cl,cr,v[p2],v[p1]);
if(!(v[p2]-v[p1]))return ;
if(l<=cl&&cr<=r)return v[p2]-v[p1];
return (l<=cl+cr>>?ask(t[p1][],t[p2][],l,r,cl,cl+cr>>):)+(r>cl+cr>>?ask(t[p1][],t[p2][],l,r,(cl+cr>>)+,cr):);
}
int main(){w[]=;
scanf("%d%d%d%d",&n,&m,&k,&opt);
for(int i=;i<=n;++i)fid[i]=i;
for(int i=;i<=m;++i){
scanf("%d%d",&x[i],&y[i]);
if(x[i]==y[i])lst[i]=i;
else if(find(x[i])!=find(y[i]))fid[fid[x[i]]]=fid[y[i]],link(x[i],n+i),link(n+i,y[i]);
else split(x[i],y[i]),lst[i]=w[y[i]]-n,cut(lst[i]+n,x[lst[i]]),cut(lst[i]+n,y[lst[i]]),
link(x[i],n+i),link(y[i],n+i);
build(rt[i],rt[i-],lst[i]);//printf("%d\n",lst[i]);
}
for(int i=,l,r;i<=k;++i){
scanf("%d%d",&l,&r);
if(opt)l^=ans,r^=ans;
ans=n-ask(rt[l-],rt[r],,l-);
printf("%d\n",ans);
}
}
GERALD07加强版:lct,主席树,边化点的更多相关文章
- BZOJ 3514: Codechef MARCH14 GERALD07加强版 [LCT 主席树 kruskal]
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 1312 Solved: 501 ...
- [BZOJ3514]CodeChef MARCH14 GERALD07加强版(LCT+主席树)
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 2177 Solved: 834 ...
- BZOJ 3514: Codechef MARCH14 GERALD07加强版( LCT + 主席树 )
从左到右加边, 假如+的边e形成环, 那么记下这个环上最早加入的边_e, 当且仅当询问区间的左端点> _e加入的时间, e对答案有贡献(脑补一下). 然后一开始是N个连通块, 假如有x条边有贡献 ...
- 【BZOJ3514】Codechef MARCH14 GERALD07加强版 LCT+主席树
题解: 还是比较简单的 首先我们的思路是 确定起点 然后之后贪心的选择边(也就是越靠前越希望选) 我们发现我们只需要将起点从后向前枚举 然后用lct维护连通性 因为强制在线,所以用主席树记录状态就可以 ...
- BZOJ3514:GERALD07加强版(LCT,主席树)
Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密. 接下来 ...
- BZOJ 3514 GERALD07加强版 (LCT+主席树)
题目大意:给定n个点m条边无向图,每次询问求当图中有编号为[L,R]的边时,整个图的联通块个数,强制在线 神题!(发现好久以前的题解没有写完诶) 我们要求图中联通块的个数,似乎不可搞啊. 联通块个数= ...
- BZOJ_3514_Codechef MARCH14 GERALD07加强版_主席树+LCT
BZOJ_3514_Codechef MARCH14 GERALD07加强版_主席树+LCT Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. I ...
- 【BZOJ-3514】Codechef MARCH14 GERALD07加强版 LinkCutTree + 主席树
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 1288 Solved: 490 ...
- BZOJ 3514: Codechef MARCH14 GERALD07加强版(LCT + 主席树)
题意 \(N\) 个点 \(M\) 条边的无向图,询问保留图中编号在 \([l,r]\) 的边的时候图中的联通块个数. \(K\) 次询问强制在线. \(1\le N,M,K \le 200,000\ ...
随机推荐
- sbt 学习笔记(1)sbt安装和交互式界面使用
下载sbt: http://www.scala-sbt.org/download.html 解压zip文件F:\sbt-0.13.15 配置环境变量 如果需要可以修改F:\sbt-0.13.15\sb ...
- 使用 Docker 让部署 Django 项目更加轻松
作者:HelloGitHub-追梦人物 文中涉及的示例代码,已同步更新到 HelloGitHub-Team 仓库 之前一系列繁琐的部署步骤让我们感到痛苦.这些痛苦包括: 要去服务器上执行 n 条命令 ...
- 我又不是你的谁--java instanceof操作符用法揭秘
背景故事 <曾经最美>是朱铭捷演唱的一首歌曲,由陈佳明填词,叶良俊谱曲,是电视剧<水晶之恋>的主题曲.歌曲时长4分28秒. 歌曲歌词: 看不穿你的眼睛 藏有多少悲和喜 像冰雪细 ...
- springboot+thymeleaf国际化方法一:LocaleResolver
springboot中大部分有默认配置所以开发起项目来非常迅速,仅对需求项做单独配置覆盖即可 spring采用的默认区域解析器是AcceptHeaderLocaleResolver,根据request ...
- Tomcat部署项目的三个方法
所需软件安装 要想在Tomcat中部署项目前提是先要搭建好Tomcat,搭建Tomcat就离不开以下软件包的安装配置,本次演示使用Linux平台 1.JDK软件包 JDK是一切java应用程序的基础, ...
- PHP array_shift
1.函数的作用:删除数组的头个元素并返回 2.函数的参数: @params array &$array 3.需要注意的例子: <?php /** * http://php.net/ma ...
- luoguP1006 传纸条
题目描述 Description 小渊和小轩是好朋友也是同班同学,他们在一起总有谈不完的话题.一次素质拓展活动中,班上同学安排做成一个 m" role="presentation& ...
- CVE-2016-7124漏洞复现
CVE-2016-7124漏洞复现 __wakeup()魔术方法绕过 实验环境 操作机:Windows 10 服务器:apache 2.4 数据库:mysql 5.0 PHP版本:5.5 漏洞影响版本 ...
- SpringBoot:1.开启SpringBoot之旅
什么是 Spring Boot Spring Boot是Spring团队设计用来简化Spring应用的搭建和开发过程的框架.该框架对第三方库进行了简单的默认配置,通过Spring Boot构建的应用程 ...
- React学习系列之(1)简单的demo(React脚手架)
1.什么是React? React是一个一个声明式,高效且灵活的用于构建用户界面的JavaScript库.React 起源于 Facebook 的内部项目,用来架设 Instagram 的网站,并于 ...