【BZOJ-3514】Codechef MARCH14 GERALD07加强版 LinkCutTree + 主席树
3514: Codechef MARCH14 GERALD07加强版
Time Limit: 60 Sec Memory Limit: 256 MB
Submit: 1288 Solved: 490
[Submit][Status][Discuss]
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
1 3
1 2
2 1
3 2
2 2
2 3
1 5
5 5
1 2
Sample Output
1
3
1
HINT
对于100%的数据,1≤N、M、K≤200,000。
2016.2.26提高时限至60s
Source
Solution
这应该算是动态图问题吧?? 问了一下ShallWe,用LCT维护动态图问题的一种离线做法是维护一颗 时间最大生成树 ,所以这个也是一样。
思路非常的巧妙,首先维护一颗 时间最大生成树 ,按时间顺序加边。
设当前加边为$<u,v>$,如果$u$和$v$属于同一个联通块,则加入$<u,v>$必然会形成环,那么切掉这个环上的边权(时间)最小的边,连上这个边,记这个被切掉的边为$pop_{i}$
然后这个题要求联通块的个数,然后发现,对于$pop$存在一个性质:
对于一条边$x$,在边$x$和使边$x$被切的边$y$之间连上的边,是不会与使边$x$被切得边$y$出现环的,即如果$r>y>l>x$则$y$必然会使联通块-1
所以问题就可以转化为求$[l,r]$中$pop<l$的$pop$的个数,这个可以用主席树去维护,所以答案就是$N-sum$。
Code
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<cmath>
using namespace std;
#define INF 0x3fffffff
#define MAXN 400010
inline int read()
{
int x=0,f=1; char ch=getchar();
while (ch<'0' || ch>'9') {if (ch=='-') f=-1; ch=getchar();}
while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
return x*f;
}
int N,M,K,T,last;
struct EdgeNode{int u,v;}edge[MAXN];
namespace LCT
{
int fa[MAXN],son[MAXN][2],id[MAXN],tim[MAXN]; bool rev[MAXN];
inline void Init() {for (int i=1; i<=N; i++) id[i]=i,tim[i]=INF;}
inline bool is_root(int x) {return !fa[x] || son[fa[x]][0]!=x&&son[fa[x]][1]!=x;}
inline int Min(int x,int y) {return tim[x]<tim[y]? x:y;}
inline void Update(int x)
{
id[x]=x;
if (son[x][0]) id[x]=Min(id[x],id[son[x][0]]);
if (son[x][1]) id[x]=Min(id[x],id[son[x][1]]);
}
inline void Rev(int x) {if (!x) return; swap(son[x][0],son[x][1]),rev[x]^=1;}
inline void Pushdown(int x)
{
if (!x) return;
if (rev[x]) Rev(son[x][0]),Rev(son[x][1]),rev[x]^=1;
}
inline void Rotate(int x)
{
int y=fa[x],w=son[y][1]==x,z=fa[y];
son[y][w]=son[x][w^1];
if (son[x][w^1]) fa[son[x][w^1]]=y;
if (son[z][0]==y) son[z][0]=x; else if (son[z][1]==y) son[z][1]=x;
fa[x]=z; fa[y]=x; son[x][w^1]=y; Update(y);
}
int stack[MAXN];
inline void Splay(int x)
{
int t=x,top=0,y; stack[++top]=x;
while (!is_root(t)) stack[++top]=t=fa[t];
while (top) Pushdown(stack[top--]);
while (!is_root(x))
{
y=fa[x];
if (!is_root(y))
if ((son[fa[y]][0]==y)^(son[y][0]==x)) Rotate(x);
else Rotate(y);
Rotate(x);
}
Update(x);
}
inline void Access(int x) {for (int y=0; x; y=x,x=fa[x]) Splay(x),son[x][1]=y,Update(x);}
inline void Makeroot(int x) {Access(x); Splay(x); Rev(x);}
inline void Link(int x,int y) {Makeroot(x); fa[x]=y; Access(x);}
inline void Cut(int x) {Access(x); Splay(x); fa[son[x][0]]=0; son[x][0]=0; Update(x);}
inline void Cut(int x,int y) {Makeroot(x); Access(y); Cut(y);}
inline int Find(int x) {Access(x); Splay(x); while (son[x][0]) x=son[x][0]; return x;}
inline int Query(int x,int y) {Makeroot(x); Access(y); Splay(y); return id[y];}
}using namespace LCT; namespace PrTree
{
int root[MAXN],lson[MAXN*20],rson[MAXN*20],sum[MAXN*20],sz;
inline void Insert(int l,int r,int &now,int par,int val)
{
now=++sz; sum[now]=sum[par]+1;
if (l==r) {return;}
lson[now]=lson[par],rson[now]=rson[par];
int mid=(l+r)>>1;
if (val<=mid) Insert(l,mid,lson[now],lson[par],val);
else Insert(mid+1,r,rson[now],rson[par],val);
}
inline int Query(int l,int r,int L,int R,int val)
{
if (r<=val) return sum[R]-sum[L];
int mid=(l+r)>>1;
if (val<=mid) return Query(l,mid,lson[L],lson[R],val);
else return Query(l,mid,lson[L],lson[R],val)+Query(mid+1,r,rson[L],rson[R],val);
}
}using namespace PrTree;
int pop[MAXN];
int main()
{
N=read(),M=read(),K=read(),T=read();
for (int i=1; i<=M; i++) edge[i].u=read(),edge[i].v=read();
LCT::Init();
for (int i=1; i<=M; i++)
{
int u=edge[i].u,v=edge[i].v;
if (u==v) {pop[i]=i; continue;}
if (LCT::Find(u)==LCT::Find(v))
{
pop[i]=LCT::Query(u,v);
LCT::Cut(u,pop[i]); LCT::Cut(v,pop[i]);
pop[i]-=N;
}
id[i+N]=i+N,tim[i+N]=i;
LCT::Link(u,i+N); LCT::Link(v,i+N);
}
// for (int i=1; i<=M; i++) printf("%d ",pop[i]); puts("");
for (int i=1; i<=M; i++) PrTree::Insert(0,M,root[i],root[i-1],pop[i]);
while (K--)
{
int L=read(),R=read();
if (T) L^=last,R^=last;
printf("%d\n",last=N-Query(0,M,root[L-1],root[R],L-1));
}
return 0;
}
【BZOJ-3514】Codechef MARCH14 GERALD07加强版 LinkCutTree + 主席树的更多相关文章
- 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 + 主席树 )
从左到右加边, 假如+的边e形成环, 那么记下这个环上最早加入的边_e, 当且仅当询问区间的左端点> _e加入的时间, e对答案有贡献(脑补一下). 然后一开始是N个连通块, 假如有x条边有贡献 ...
- BZOJ 3514 Codechef MARCH14 GERALD07加强版 Link-Cut-Tree+划分树
题目大意: 给定n个点m条边的无向图.求问当图中仅仅有[编号在[l,r]区间内]的边存在时图中的联通块个数 强制在线 注意联通块是指联通了就是同一块,不是Tarjan求的那种块 看到这题的那一刻我就想 ...
- [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加强版 (CHEF AND GRAPH QUERIES)
[BZOJ3514] Codechef MARCH14 GERALD07加强版 (CHEF AND GRAPH QUERIES) 题意 \(N\) 个点 \(M\) 条边的无向图,\(K\) 次询问保 ...
- BZOJ 3514: Codechef MARCH14 GERALD07加强版(LCT + 主席树)
题意 \(N\) 个点 \(M\) 条边的无向图,询问保留图中编号在 \([l,r]\) 的边的时候图中的联通块个数. \(K\) 次询问强制在线. \(1\le N,M,K \le 200,000\ ...
- BZOJ 3514: Codechef MARCH14 GERALD07加强版 (LCT维护最大生成树+主席树)
题意 给出nnn个点,mmm条边.多次询问,求编号在[l,r][l,r][l,r]内的边形成的联通块的数量,强制在线. 分析 LCTLCTLCT维护动态最大生成树,先将每条边依次加进去,若形成环就断掉 ...
- 【刷题】BZOJ 3514 Codechef MARCH14 GERALD07加强版
Description N个点M条边的无向图,询问保留图中编号在[l,r]的边的时候图中的联通块个数. Input 第一行四个整数N.M.K.type,代表点数.边数.询问数以及询问是否加密. 接下来 ...
- 【BZOJ3514】Codechef MARCH14 GERALD07加强版 LCT+主席树
题解: 还是比较简单的 首先我们的思路是 确定起点 然后之后贪心的选择边(也就是越靠前越希望选) 我们发现我们只需要将起点从后向前枚举 然后用lct维护连通性 因为强制在线,所以用主席树记录状态就可以 ...
随机推荐
- PHP 单例模式
一.什么是单例模式? 1.含义 作为对象的创建模式,单例模式确保某一个类只有一个实例,而且自行实例化并向整个系统全局地提供这个实例.它不会创建实例副本,而是会向单例类内部存储的实例返回一个引用. 2. ...
- Javaweb项目框架搭建-准备篇
前言Java从大二开始学习到现在大四也有差不多两年了,但是由于之前一直在玩,没有认真学过,直到现在才开始重新学习.也是很凑巧,看到了黄勇老师的<架构探险>,于是便开始学习写Java Web ...
- solr添加多个core
在D:\solr\solr_web\solrhome文件夹下: 1)创建core0文件夹 2)复制D:\solr\solr_web\solrhome\configsets\basic_configs/ ...
- 30分钟让网站支持HTTPS
对于一个良好和安全的网络——并且也为了更快的性能,新的API网络例如Service Workers,更佳的搜索排名,还有——在你的网站上使用HTTPS是关键.这里我会指导大家如何轻松搞定. 我不是安全 ...
- mac 抓包工具charles v3.9.3 安装破解步骤
一.下载 先到它的官网http://www.charlesproxy.com/可下载到最新版本,这个下载有点慢,我已经将它放到网盘中了:http://pan.baidu.com/s/1skTXRIl ...
- PHP相关笔记
扩展包(相关链接):https://packagist.org/: 插件postman主要应用于web开发时get.post请求时查看其响应:
- Linux下MySQL慢查询分析mysqlsla安装使用
说明: 操作系统:CentOS 5.X 64位 MySQL版本:mysql-5.5.35 MySQL配置文件:/etc/my.cnf MySQL 数据库存放目录:/data/mysql 实现目的:开启 ...
- Windows Server 2012 虚拟化实战:网络(一)
虚拟化对于计算的抽象,大家可能相对熟悉,也许都有在单机使用诸如Virtual PC或者Virtual Box的经验.使用的这些虚拟化软件的第一印象就是我们的CPU可以同时运行多套不同的操作系统,并且其 ...
- 萌新笔记——git的问题(error: object file .git/objects/* is empty...)的解决方案及对git版本库文件的了解
由于操作不当,导致git版本库出了大问题,如下所示: error: object file .git/objects/8b/61d0135d3195966b443f6c73fb68466264c68e ...
- shell脚本实现算术运算且输入的不能为非数字的值
#!/bin/bash c= ] do echo "请输入第一个数" read a echo "请输入第二个数" read b ]* ]] && ...