【bzoj3514】Codechef MARCH14 GERALD07加强版 LCT+可持久化线段树
题目描述
N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数。
输入
第一行四个整数N、M、K、type,代表点数、边数、询问数以及询问是否加密。
接下来M行,代表图中的每条边。
接下来K行,每行两个整数L、R代表一组询问。对于type=0的测试点,读入的L和R即为询问的L、R;对于type=1的测试点,每组询问的L、R应为L xor lastans和R xor lastans。
输出
K行每行一个整数代表该组询问的联通块个数。
样例输入
3 5 4 0
1 3
1 2
2 1
3 2
2 2
2 3
1 5
5 5
1 2
样例输出
2
1
3
1
题解
LCT+可持久化线段树
首先考虑离线怎么做:
考虑按照时间顺序加入每一条边k的过程所带来的影响:当加入一条边时,
如果这两个点原来不连通,则加入这条边后这两个点连通。故左端点在[1,k],右端点在k以后的询问中,这两个点都是连通的。所以把左端点[1,k]范围内的边数+1.
如果这两个点原来是连通的,则加入这条边后会形成一个环。我们考虑这个环上的出现时刻最早的边,不需要时间早于该点即可是这个环上所有点连通。仔细推一推可以发现相当于把左端点[最早时刻,k]范围内的边数+1。
把询问按照右端点时间排序,那么要做的就是:(1)维护环上出现时刻最早的边:使用LCT维护出现时间的最大生成树,并把边权转化为点权处理(a<->b变为a<->c<->b);(2)支持区间修改、单点查询。使用线段树即可。
那么如果是强制在线呢?使用可持久化线段树,一个版本的可持久化线段树的每个节点的含义是:左端点在当前节点,右端点为该版本的询问的答案。每次需要再原版本线段树的基础上进行区间修改。这里使用可标记永久化的方式来维护。
所以对于询问[l,r]直接在r版本的可持久化线段树中查询l节点的值即为当前生成森林的边数,使用n减去该数即为连通块数。
时间复杂度$O(n\log n)$,常数巨大。
#include <cstdio>
#include <cstring>
#include <algorithm>
#define N 400010
using namespace std;
int px[N >> 1] , py[N >> 1] , fa[N] , c[2][N] , mn[N] , rev[N] , ls[N * 40] , rs[N * 40] , sum[N * 40] , tot , root[N >> 1];
inline void pushup(int x)
{
mn[x] = min(x , min(mn[c[0][x]] , mn[c[1][x]]));
}
inline void pushdown(int x)
{
if(rev[x])
{
int l = c[0][x] , r = c[1][x];
swap(c[0][l] , c[1][l]) , swap(c[0][r] , c[1][r]);
rev[l] ^= 1 , rev[r] ^= 1 , rev[x] = 0;
}
}
inline bool isroot(int x)
{
return c[0][fa[x]] != x && c[1][fa[x]] != x;
}
void update(int x)
{
if(!isroot(x)) update(fa[x]);
pushdown(x);
}
inline void rotate(int x)
{
int y = fa[x] , z = fa[y] , l = (c[1][y] == x) , r = l ^ 1;
if(!isroot(y)) c[c[1][z] == y][z] = x;
fa[x] = z , fa[y] = x , fa[c[r][x]] = y , c[l][y] = c[r][x] , c[r][x] = y;
pushup(y) , pushup(x);
}
inline void splay(int x)
{
int y , z;
update(x);
while(!isroot(x))
{
y = fa[x] , z = fa[y];
if(!isroot(y)) rotate((c[0][y] == x) ^ (c[0][z] == y) ? x : y);
rotate(x);
}
}
inline void access(int x)
{
int t = 0;
while(x) splay(x) , c[1][x] = t , pushup(x) , t = x , x = fa[x];
}
inline int find(int x)
{
while(fa[x]) x = fa[x];
return x;
}
inline void makeroot(int x)
{
access(x) , splay(x) , swap(c[0][x] , c[1][x]) , rev[x] ^= 1;
}
inline void link(int x , int y)
{
makeroot(x) , fa[x] = y;
}
inline void split(int x , int y)
{
makeroot(x) , access(y) , splay(y);
}
inline void cut(int x , int y)
{
split(x , y) , fa[x] = c[0][y] = 0 , pushup(y);
}
void update(int b , int e , int l , int r , int x , int &y)
{
y = ++tot , sum[y] = sum[x] , ls[y] = ls[x] , rs[y] = rs[x];
if(b <= l && r <= e)
{
sum[y] ++ ;
return;
}
int mid = (l + r) >> 1;
if(b <= mid) update(b , e , l , mid , ls[x] , ls[y]);
if(e > mid) update(b , e , mid + 1 , r , rs[x] , rs[y]);
}
int query(int p , int l , int r , int x)
{
if(l == r) return sum[x];
int mid = (l + r) >> 1;
if(p <= mid) return sum[x] + query(p , l , mid , ls[x]);
else return sum[x] + query(p , mid + 1 , r , rs[x]);
}
int main()
{
int n , m , k , type , i , x , y , last = 0;
scanf("%d%d%d%d" , &n , &m , &k , &type);
for(i = 1 ; i <= m + n ; i ++ ) mn[i] = i;
mn[0] = 1 << 30;
for(i = 1 ; i <= m ; i ++ )
{
scanf("%d%d" , &px[i] , &py[i]) , px[i] += m , py[i] += m;
if(px[i] == py[i]) root[i] = root[i - 1];
else if(find(px[i]) != find(py[i])) link(px[i] , i) , link(py[i] , i) , update(1 , i , 1 , m , root[i - 1] , root[i]);
else
{
split(px[i] , py[i]) , x = mn[py[i]] , cut(px[x] , x) , cut(py[x] , x);
link(px[i] , i) , link(py[i] , i) , update(x + 1 , i , 1 , m , root[i - 1] , root[i]);
}
}
while(k -- )
{
scanf("%d%d" , &x , &y);
if(type) x ^= last , y ^= last;
printf("%d\n" , last = n - query(x , 1 , m , root[y]));
}
return 0;
}
【bzoj3514】Codechef MARCH14 GERALD07加强版 LCT+可持久化线段树的更多相关文章
- BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT+可持久化线段树
自己独自想出来并切掉还是很开心的~ Code: #include <bits/stdc++.h> #define N 400005 #define inf 1000000000 #defi ...
- [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 ...
- bzoj 3514: GERALD07加强版 lct+可持久化线段树
题目大意: N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. 题解: 这道题考试的时候没想出来 于是便爆炸了 结果今天下午拿出昨天准备的题表准备做题的时候 题表里就有这题 ...
- 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,代表点数.边数.询问数以及询问是否加密.接下来M ...
- BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT维护最大生成树 主席树
题面 考虑没有询问,直接给你一个图问联通块怎么做. 并查集是吧. 现在想要动态地做,那么应该要用LCT. 考虑新加进来一条边,想要让它能够减少一个联通块的条件就是现在边的两个端点还没有联通. 如果联通 ...
- 【LCT+主席树】BZOJ3514 Codechef MARCH14 GERALD07加强版
3514: Codechef MARCH14 GERALD07加强版 Time Limit: 60 Sec Memory Limit: 256 MBSubmit: 2023 Solved: 778 ...
- BZOJ 3514: Codechef MARCH14 GERALD07加强版( LCT + 主席树 )
从左到右加边, 假如+的边e形成环, 那么记下这个环上最早加入的边_e, 当且仅当询问区间的左端点> _e加入的时间, e对答案有贡献(脑补一下). 然后一开始是N个连通块, 假如有x条边有贡献 ...
随机推荐
- LVS NAT,DR,TUN三种负载原理
负载均衡简单介绍 用通俗的话来说负载均衡,就是通过不同的调度机制将用户的请求分派到后端不同的服务器.缓解服务器的请求压力,实现负载均衡的方案有多种,下面简单说说了解的几种方式: DNS 负载:利用DN ...
- vue项目中缓存问题
单页面应用总是存在缓存问题,特别是在微信端,更新页面之后访问的还是老页面,缓存的问题是因为用户访问的脚本地址并没有改变,浏览器就会读取原来的脚本 网上有几种解决办法,首先列举一下 1.加meta,禁止 ...
- koa2 mongdb 做后端接口的小demo
现在前端全栈里面有一种技术栈比较火 前端使用 vue 或者react 后端使用 koa2 mysql数据库 或者mongdb做数据储存 但是基本这样的全栈教程 都要收费 收费就收费吧 但是 有没有遇到 ...
- Hadoop(21)-数据清洗(ELT)简单版
有一个诸如这样的log日志 去除长度不合法,并且状态码不正确的记录 LogBean package com.nty.elt; /** * author nty * date time 2018-12- ...
- 使用C6748和C5509A对nRF24L01驱动进行数据传输
1. 写在前面 今天下午做了一个C5509A和C6748两个DSP的数据传输,经由RF24L01设备传输,都是模拟SPI协议,对于两个DSP来说,无非是配GPIO引脚,写好时序和延时.C5509A的G ...
- 转载:小白使用eclipse提交到GitHub (详细步骤)
本篇文章只是备忘,以防电脑重装找不到记录 教程:https://blog.csdn.net/bendanany/article/details/78891804
- 生产Web架构优化方案(动态转静态)
Infi-chu: http://www.cnblogs.com/Infi-chu/ 一.门户新闻业务: 1. 特点:网页一旦发布,再次改动网页内容的几率很低,新闻业务内容的静态化相对比较简单 2. ...
- TopCoder SRM 489 Div1 Lev3:AppleTree
挺优秀的一道题,想出做法时有些惊艳. 题意: 数轴上有\(D\)个连续整数刻度,有\(N\)棵树要种在这些刻度上,其中第\(i\)棵与两旁(如果有的话)相邻的树至少要相距\(R_i\),问方法数. \ ...
- REPLACE(替换字段内容)
语法: REPLACE <str1> WITH <str2> INTO <c> [LENGTH <l> ]. ABAP/4 搜索字段 <c> ...
- shell重温---基础篇(参数传递&echo命令)
经过前两天的学习,关于shell的基础算是知道的一般般啦,最起码不算是小白了(纯属意淫).今天就来点干货哈. 首先是运行shell脚本时的参数传递.脚本内获取参数的格式为$n.n代表了一个数字,例 ...