BZOJ3514 GERALD07加强版
GERALD07
Description
N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数。
Input
第一行四个整数N、M、K、type,代表点数、边数、询问数以及询问是否加密。
接下来M行,代表图中的每条边。
接下来K行,每行两个整数L、R代表一组询问。对于type=0的测试点,读入的L和R即为询问的L、R;对于type=1的测试点,每组询问的L、R应为L xor lastans和R xor lastans。
Output
K行每行一个整数代表该组询问的联通块个数。
Sample Input
3 5 4 0
1 3
1 2
2 1
3 2
2 2
2 3
1 5
5 5
1 2
Sample Output
2
1
3
1
HINT
对于100%的数据,1≤N、M、K≤200,000。
hzwer的题解
连通块的个数可以用n-生成树的边数来计算。
有一个比较猎奇的做法:首先把边依次加到图中,若当前这条边与图中的边形成了环,那么把这个环中最早加进来的边弹出去,并将每条边把哪条边弹了出去记录下来:ntr[i] = j,特别地,要是没有弹出边,ntr[i] = 0;
这个可以用LCT来弄。
然后对于每个询问,我们的对l~r中ntr小于l的边计数,并用n减去这个值。
正确性可以YY一下:
- 如果一条边的ntr >= l,那么显然他可以与从l ~ r中的边形成环,那么它对答案没有贡献。
- 反之如果一条边的ntr < l那么它与从l ~ r中的边是不能形成环的,那么他对答案的贡献为-1。
对于查询从l ~ r中有多少边的ntr小于l,我反正是用的函数式线段树。时间复杂度\(O((M+K)\log N)\)。
co int N=4e5+1,M=2e5+1,INF=0x3f3f3f3f;
bool type;
int n,m,Q,lastans,top,tot,sz;
int s[N],st[M],root[M];
int c[N][2],fa[N],val[N],mn[N];
int sum[4000005],ls[4000005],rs[4000005];
bool rev[N];
struct edge{int u,v;}e[M];
bool isroot(int x){
return c[fa[x]][0]!=x&&c[fa[x]][1]!=x;
}
void update(int x){
int l=c[x][0],r=c[x][1];
mn[x]=x;
if(val[mn[l]]<val[mn[x]]) mn[x]=mn[l];
if(val[mn[r]]<val[mn[x]]) mn[x]=mn[r];
}
void pushdown(int x){
int l=c[x][0],r=c[x][1];
if(rev[x]){
std::swap(c[x][0],c[x][1]);
rev[l]^=1,rev[r]^=1,rev[x]=0;
}
}
void rotate(int x){
int y=fa[x],z=fa[y],l,r;
l=c[y][1]==x,r=l^1;
if(!isroot(y)) c[z][c[z][1]==y]=x;
fa[y]=x,fa[x]=z,fa[c[x][r]]=y;
c[y][l]=c[x][r],c[x][r]=y;
update(y),update(x);
}
void splay(int x){
top=0,s[++top]=x;
for(int i=x;!isroot(i);i=fa[i]) s[++top]=fa[i];
for(int i=top;i;--i) pushdown(s[i]);
while(!isroot(x)){
int y=fa[x],z=fa[y];
if(!isroot(y)) rotate(c[y][0]==x^c[z][0]==y?x:y);
rotate(x);
}
}
void access(int x){
for(int t=0;x;x=fa[t=x])
splay(x),c[x][1]=t,update(x);
}
void makeroot(int x){
access(x),splay(x),rev[x]^=1;
}
void link(int x,int y){
makeroot(x),fa[x]=y;
}
void cut(int x,int y){
makeroot(x),access(y),splay(y);
c[y][0]=fa[x]=0;
}
int find(int x){
access(x),splay(x);
while(c[x][0]) x=c[x][0];
return x;
}
int query(int x,int y){
makeroot(x),access(y),splay(y);
return mn[y];
}
void insert(int l,int r,int x,int&y,int val){
y=++sz;
sum[y]=sum[x]+1;
if(l==r) return;
ls[y]=ls[x],rs[y]=rs[x];
int mid=(l+r)>>1;
if(val<=mid) insert(l,mid,ls[x],ls[y],val);
else insert(mid+1,r,rs[x],rs[y],val);
}
int query(int l,int r,int x,int y,int val){
if(r==val) return sum[y]-sum[x];
int mid=(l+r)>>1;
if(val<=mid) return query(l,mid,ls[x],ls[y],val);
else return sum[ls[y]]-sum[ls[x]]+query(mid+1,r,rs[x],rs[y],val);
}
int main(){
// freopen(".in","r",stdin);
// freopen(".out","w",stdout);
read(n),read(m),read(Q),read(type);
val[0]=INF;
for(int i=1;i<=n;++i) mn[i]=i,val[i]=INF;
for(int i=1;i<=m;++i)
read(e[i].u),read(e[i].v);
tot=n;
for(int i=1;i<=m;++i){
int u=e[i].u,v=e[i].v;
if(u==v){
st[i]=i;continue;
}
if(find(u)==find(v)){
int t=query(u,v),x=val[t];
st[i]=x;
cut(e[x].u,t),cut(e[x].v,t);
}
++tot;
mn[tot]=tot,val[tot]=i;
link(u,tot),link(v,tot);
}
for(int i=1;i<=m;++i)
insert(0,m,root[i-1],root[i],st[i]);
for(int i=1;i<=Q;++i){
int l=read<int>(),r=read<int>();
if(type) l^=lastans,r^=lastans;
lastans=n-query(0,m,root[l-1],root[r],l-1);
printf("%d\n",lastans);
}
return 0;
}
BZOJ3514 GERALD07加强版的更多相关文章
- BZOJ3514:GERALD07加强版(LCT,主席树)
Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密. 接下来 ...
- [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加强版 LinkCutTree + 主席树
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 1288 Solved: 490 ...
- 【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预处理+主席树
Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 1951 Solved: 746[Submi ...
- [BZOJ 3514]Codechef MARCH14 GERALD07加强版 (CHEF AND GRAPH QUERIES)
[BZOJ3514] Codechef MARCH14 GERALD07加强版 (CHEF AND GRAPH QUERIES) 题意 \(N\) 个点 \(M\) 条边的无向图,\(K\) 次询问保 ...
- BZOJ 3514: Codechef MARCH14 GERALD07加强版( LCT + 主席树 )
从左到右加边, 假如+的边e形成环, 那么记下这个环上最早加入的边_e, 当且仅当询问区间的左端点> _e加入的时间, e对答案有贡献(脑补一下). 然后一开始是N个连通块, 假如有x条边有贡献 ...
- BZOJ 3514: Codechef MARCH14 GERALD07加强版 [LCT 主席树 kruskal]
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 1312 Solved: 501 ...
- BZOJ_3514_Codechef MARCH14 GERALD07加强版_主席树+LCT
BZOJ_3514_Codechef MARCH14 GERALD07加强版_主席树+LCT Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. I ...
随机推荐
- axios 使用入门
[Vue 牛刀小试]:第十五章 - 传统开发模式下的 axios 使用入门 一.前言# 在没有接触 React.Angular.Vue 这类 MVVM 的前端框架之前,无法抛弃 Jquery 的重 ...
- 性能测试监控:Jmeter+Collectd+Influxdb+Grafana
系统性能指标图示例: 采集数据(collectd)-> 存储数据(influxdb) -> 显示数据(grafana) InfluxDB 是 Go 语言开发的一个开源分布式时序数据库,非常 ...
- URI和URL的关系与区别
首先给大家举个例子,有一家公司的总经理,某天,给了我一张名片,上面写了他的头衔,北京XXX公司总经理 张三,还有他的办公室地址,北京市海淀区长安街35号北京XXX公司总经理办公室,那么,我以后给我的朋 ...
- 第1章:LeetCode--基础部分
LeetCode刷题指导(不能只实现功能就行需要尽量写最优解): 不可能刷遍所有题,只能通过刷题来恢复写代码的功力,熟悉常用算法(暴力算法.冒泡排序/快速排序.strStr KMP算法.二叉树遍历DF ...
- C++打印水仙花数
#include <iostream> #include <Windows.h> using namespace std; int main(void) { int a, b, ...
- 数据结构-链式队列-C++
用链表搭建的栈与队列相对简单,队列的特点是先进先出,不啰嗦了,由于代码比较简单,相信光顾的人不会太多,下面直接贴代码. 头文件 #ifndef QUEUELI_H #define QUEUELI_H ...
- adb连接安卓设备的2种方式
一.usb连接 安卓设备打开开发者模式,启用usb调试 CMD窗口输入adb devices,此时可以看到自己的设备 PS:无法看到自己设备时,查看手机USB调试是否打开:PC端是否安装手机驱动. 二 ...
- [Luogu5324][BJOI2019]删数(线段树)
CF风格题,先猜结论,记数列中i这个数共出现了cnt[i]次,那么所有区间[i-cnt[i]+1,i]的并集的补集大小就是答案. 于是我们只需要线段树维护每个位置是否被某个区间覆盖到即可,对于整体加减 ...
- Integer源码解析
版权声明:本文为博主原创文章,未经博主允许不得转载. https://blog.csdn.net/wangyangzhizhou/article/details/77196626 概况 Java的In ...
- 腾讯域名使用百度CDN加速配置
1.百度CDN资源包购买 购买地址 https://console.bce.baidu.com/cdn/#/cdn/package/create 我比较穷所以买的是18块100G的资源包. 2.添加域 ...