BZOJ 4025 二分图 LCT维护最大生成树
怎么说呢,我也不知道该咋讲,你就手画一下然后 yy 一下就发现这么做是对的.
为什么我明明都想出来了,却还是讲不出来啊~
#include <cstdio>
#include <vector>
#include <algorithm>
#define N 800004
#define inf 1000000000
#define setIO(s) freopen(s".in","r",stdin) ,freopen(s".out","w",stdout)
using namespace std;
int n,m,T,cnt;
struct Edge
{
int u,v,s,t;
Edge(int u=0,int v=0,int s=0,int t=0):u(u),v(v),s(s),t(t){}
}e[N];
struct Link_Cut_Tree
{
#define lson p[x].ch[0]
#define rson p[x].ch[1]
int sta[N];
struct Node
{
int min,id,val,size,rev,f,ch[2];
}p[N];
int get(int x)
{
return p[p[x].f].ch[1]==x;
}
int isrt(int x)
{
return !(p[p[x].f].ch[0]==x||p[p[x].f].ch[1]==x);
}
void pushup(int x)
{
p[x].size=(x>n);
p[x].min=p[x].val;
p[x].id=x;
if(lson)
{
p[x].size+=p[lson].size;
if(p[lson].min<p[x].min) p[x].min=p[lson].min,p[x].id=p[lson].id;
}
if(rson)
{
p[x].size+=p[rson].size;
if(p[rson].min<p[x].min) p[x].min=p[rson].min,p[x].id=p[rson].id;
}
}
void mark(int x)
{
if(x) p[x].rev^=1,swap(lson,rson);
}
void pushdown(int x)
{
if(x&&p[x].rev)
{
p[x].rev=0;
if(lson) mark(lson);
if(rson) mark(rson);
}
}
void rotate(int x)
{
int old=p[x].f,fold=p[old].f,which=get(x);
if(!isrt(old)) p[fold].ch[p[fold].ch[1]==old]=x;
p[old].ch[which]=p[x].ch[which^1],p[p[old].ch[which]].f=old;
p[x].ch[which^1]=old,p[old].f=x,p[x].f=fold;
pushup(old),pushup(x);
}
void splay(int x)
{
int u=x,v=0,fa;
for(sta[++v]=u;!isrt(u);u=p[u].f) sta[++v]=p[u].f;
for(;v;--v) pushdown(sta[v]);
for(u=p[u].f;(fa=p[x].f)!=u;rotate(x))
if(p[fa].f!=u)
rotate(get(fa)==get(x)?fa:x);
}
int findroot(int x)
{
Access(x),splay(x);
for(;lson;) x=lson;
return x;
}
void Access(int x)
{
for(int y=0;x;y=x,x=p[x].f)
splay(x),rson=y,pushup(x);
}
void makeroot(int x)
{
Access(x),splay(x),mark(x);
}
void split(int x,int y)
{
makeroot(x),Access(y),splay(y);
}
void link(int x,int y)
{
makeroot(x),p[x].f=y;
}
void cut(int x,int y)
{
makeroot(x),Access(y),splay(y);
p[y].ch[0]=p[x].f=0;
pushup(y);
}
#undef lson
#undef rson
}lct;
int vised[N],sum[N];
vector<int>Add[N],Del[N];
void add_edge(int id)
{
int u=e[id].u;
int v=e[id].v;
int now=id+n;
if(u==v)
{
++sum[e[id].s];
--sum[e[id].t];
}
else
{
if(lct.findroot(u)==lct.findroot(v))
{
lct.split(u,v);
int cur=lct.p[v].id;
if(lct.p[v].size%2==0)
{
++sum[e[id].s];
--sum[min(e[cur-n].t, e[id].t) ];
}
if(lct.p[cur].val<e[id].t)
{
lct.cut(cur, e[cur-n].u);
lct.cut(cur, e[cur-n].v);
lct.p[now].val=e[id].t;
lct.pushup(now);
lct.link(u,now);
lct.link(now,v);
vised[cur-n]=1;
}
}
else
{
lct.p[now].val=e[id].t;
lct.pushup(now);
lct.link(u,now);
lct.link(v,now);
}
}
}
void delete_edge(int id)
{
if(vised[id] || e[id].u==e[id].v) return;
int u=e[id].u;
int v=e[id].v;
lct.cut(id+n,u);
lct.cut(id+n,v);
}
int main()
{
int i,j;
// setIO("input");
scanf("%d%d%d",&n,&m,&T);
for(i=1;i<=n;++i) lct.p[i].val=inf, lct.pushup(i);
for(i=1;i<=m;++i)
{
int u,v,s,t;
scanf("%d%d%d%d",&u,&v,&s,&t);
e[i]=Edge(u,v,s,t);
if(s<t)
{
Add[s].push_back(i);
Del[t].push_back(i);
}
}
for(i=0;i<T;++i)
{
for(j=0;j<(int)Del[i].size();++j)
{
delete_edge(Del[i][j]);
}
for(j=0;j<(int)Add[i].size();++j)
{
add_edge(Add[i][j]);
}
if(i>0) sum[i]+=sum[i-1];
if(sum[i]>0) printf("No\n");
else printf("Yes\n");
}
return 0;
}
BZOJ 4025 二分图 LCT维护最大生成树的更多相关文章
- bzoj 4025 二分图 lct
题目传送门 题解: 首先关于二分图的性质, 就是没有奇环边. 题目其实就是让你判断每个时段之内有没有奇环. 其次 lct 只能维护树,(反正对于我这种菜鸟选手只会维护树), 那么对于一棵树来说, 填上 ...
- bzoj 4025 二分图 分治+并查集/LCT
bzoj 4025 二分图 [题目大意] 有n个点m条边,边会在start时刻出现在end时刻消失,求对于每一段时间,该图是不是一个二分图. 判断二分图的一个简单的方法:是否存在奇环 若存在奇环,就不 ...
- [BZOJ 4025]二分图(线段树分治+带边权并查集)
[BZOJ 4025]二分图(线段树分治+带边权并查集) 题面 给出一个n个点m条边的图,每条边会在时间s到t出现,问每个时间的图是否为一个二分图 \(n,m,\max(t_i) \leq 10^5\ ...
- bzoj 4025 二分图——线段树分治+LCT
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4025 线段树分治,用 LCT 维护链的长度即可.不过很慢. 正常(更快)的方法应该是线段树分 ...
- bzoj 4736: 温暖会指引我们前行 (LCT 维护最大生成树)
链接:https://www.lydsy.com/JudgeOnline/problem.php?id=4736 题面: 寒冬又一次肆虐了北国大地 无情的北风穿透了人们御寒的衣物 可怜虫们在冬夜中发出 ...
- BZOJ 4025: 二分图 [线段树CDQ分治 并查集]
4025: 二分图 题意:加入边,删除边,查询当前图是否为二分图 本来想练lct,然后发现了线段树分治的做法,感觉好厉害. lct做法的核心就是维护删除时间的最大生成树 首先口胡一个分块做法,和hno ...
- 【刷题】BZOJ 4025 二分图
Description 神犇有一个n个节点的图.因为神犇是神犇,所以在T时间内一些边会出现后消失.神犇要求出每一时间段内这个图是否是二分图.这么简单的问题神犇当然会做了,于是他想考考你. Input ...
- LOJ #121. 「离线可过」动态图连通性 LCT维护最大生成树
这个还是比较好理解的. 你考虑如果所有边构成一棵树的话直接用 LCT 模拟一波操作就行. 但是可能会出现环,于是我们就将插入/删除操作按照时间排序,然后依次进行. 那么,我们就要对我们维护的生成树改变 ...
- BZOJ3514 Codechef MARCH14 GERALD07加强版 LCT维护最大生成树 主席树
题面 考虑没有询问,直接给你一个图问联通块怎么做. 并查集是吧. 现在想要动态地做,那么应该要用LCT. 考虑新加进来一条边,想要让它能够减少一个联通块的条件就是现在边的两个端点还没有联通. 如果联通 ...
随机推荐
- Nginx关联php安装及启动
Nginx 1.10.2 php 5.6.30 [root@nginx local]# cat /etc/redhat-release CentOS Linux release 7.5.1804 (C ...
- SAS学习笔记13 SAS数据清洗和加工(续)
查找缺失值 cha[*]和num[*]是建立数组cha和num,但不指定数组中的元素数 自动变量_character_表示数据集中的所有字符型变量 自动变量_numeric_表示数据集中的所有数值型变 ...
- Ubuntu部署ftp服务器
Ubuntu 16.04 FTP服务器安装及配置 FTP File Transfer Protocol文件传输协议,两台计算机传送文件的协议,客户端可以通过FTP命令从服务器下载,上传文件,修 ...
- 在oracle表中增加、修改、删除字段,表的重命名,字段顺序调整
增加字段语法:alter table tablename add (column datatype [default value][null/not null],….); 说明:alter table ...
- IntelliJ Idea清除Open Recent里面的项目列表
2种方法清除IntelliJ Idea 中 Open Recent里面的项目列表 第一种方法: 如下图: Open Recent -> Manage Projects Recent Projec ...
- javascript的装载和执行
前言 为什么要采用js来create一个script标签,设置src然后append到head中,而不是直接使用script标签,这样不是更简单点吗? javascript的装载和执行 首先,我想说一 ...
- UDP及操作系统理论
UDP介绍 udp协议又称用户数据报协议 在OSI七层模型中,它于TCP共同存在于传输层 仅用于不要求可靠性,不要求分组顺序且数据较小的简单传输,力求速度 UDP结合socket用法 1.创建sock ...
- springload热更新的优缺点
java开发web应用没有.net的方便快捷, 原因是传统开发模式下新增修改代码后要查看效果, 一般要重启应用, 导致浪费了许多无谓的时间,没有.net的高效, 任意更新文件实时生效. 但是有个叫sp ...
- CLR ATL
前段时间,帮人改了个项目,里面明明感觉是MFC,但是却调用C#的类函数,用的都是gcnew指针,凭借着对C#的熟悉,一点一点的实验,终于帮人把程序改好了,但是却不知道到底是什么东西,C#和MFC的混合 ...
- Linux下zookeeper集群搭建
Linux下zookeeper集群搭建 部署前准备 下载zookeeper的安装包 http://zookeeper.apache.org/releases.html 我下载的版本是zookeeper ...