【BZOJ1969】航线规划(Link-Cut Tree)

题面

BZOJ

题解

删边操作

套路呀

离线读入倒过来做

变成加边操作

现在考虑怎么确定两点直接的关键路径条数

如果是一棵树,那么每条边都是关键路径

在一棵树的基础上

如果连接了两点

那么,两点之间原来的路径一定都不是关键路径

所以,弄一个\(LCT\)

每次维护加边

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<cstring>
#include<cmath>
#include<algorithm>
#include<set>
#include<map>
#include<vector>
#include<queue>
using namespace std;
#define MAX 52000
#define lson (t[x].ch[0])
#define rson (t[x].ch[1])
inline int read()
{
int x=0,t=1;char ch=getchar();
while((ch<'0'||ch>'9')&&ch!='-')ch=getchar();
if(ch=='-')t=-1,ch=getchar();
while(ch<='9'&&ch>='0')x=x*10+ch-48,ch=getchar();
return x*t;
}
map<pair<int,int>,int> M;
struct qq{int opt,ans;int u,v;}q[MAX];
struct Line{int v,next;}e[MAX*4];
struct edge{int u,v,br;}E[MAX*4];
int h[MAX],cnt=1,tot,n,m;
int S[MAX<<2],top;
inline void Add(int u,int v){e[cnt]=(Line){v,h[u]};h[u]=cnt++;}
struct Node
{
int ch[2],ff;
int sum,rev,v;
int ly;
}t[MAX<<2];
bool isroot(int x){return t[t[x].ff].ch[0]!=x&&t[t[x].ff].ch[1]!=x;}
void pushup(int x){t[x].sum=t[lson].sum+t[rson].sum+t[x].v;}
void rotate(int x)
{
int y=t[x].ff,z=t[y].ff;
int k=t[y].ch[1]==x;
if(!isroot(y))t[z].ch[t[z].ch[1]==y]=x;t[x].ff=z;
t[y].ch[k]=t[x].ch[k^1];t[t[x].ch[k^1]].ff=y;
t[x].ch[k^1]=y;t[y].ff=x;
pushup(y);pushup(x);
}
void putrev(int x){swap(lson,rson);t[x].rev^=1;}
void putly(int x){t[x].ly=1;t[x].sum=t[x].v=0;}
void pushdown(int x)
{
if(t[x].rev)
{
if(lson)putrev(lson);
if(rson)putrev(rson);
t[x].rev^=1;
}
if(t[x].ly)
{
if(lson)putly(lson);
if(rson)putly(rson);
t[x].ly=0;
}
}
void Splay(int x)
{
S[top=1]=x;
for(int i=x;!isroot(i);i=t[i].ff)S[++top]=t[i].ff;
while(top)pushdown(S[top--]);
while(!isroot(x))
{
int y=t[x].ff,z=t[y].ff;
if(!isroot(y))
(t[y].ch[1]==x)^(t[z].ch[1]==y)?rotate(x):rotate(y);
rotate(x);
}
}
void access(int x){for(int y=0;x;y=x,x=t[x].ff)Splay(x),t[x].ch[1]=y,pushup(x);}
void makeroot(int x){access(x);Splay(x);putrev(x);}
void split(int x,int y){makeroot(x);access(y);Splay(y);}
void cut(int x,int y){split(x,y);t[y].ch[0]=t[x].ff=0;pushup(y);}
void link(int x,int y){makeroot(x);t[x].ff=y;}
int findroot(int x){access(x);Splay(x);while(lson)x=lson;return x;}
int main()
{
n=read();m=read();
for(int i=1;i<=m;++i)
{
int u=read(),v=read();
if(u>v)swap(u,v);
E[i]=(edge){u,v};
M[make_pair(u,v)]=i;
t[i+n].v=1;
}
while(233)
{
int c=read();if(c==-1)break;
int u=read(),v=read();if(u>v)swap(u,v);
q[++tot]=(qq){c,0,u,v};
if(!c)E[q[tot].ans=M[make_pair(u,v)]].br=1;
}
for(int i=1;i<=m;++i)
if(!E[i].br)
{
if(findroot(E[i].u)!=findroot(E[i].v))
link(E[i].u,i+n),link(E[i].v,i+n);
else split(E[i].u,E[i].v),putly(E[i].v);
}
for(int i=tot;i;--i)
{
if(q[i].opt)
{
split(q[i].u,q[i].v);
q[i].ans=t[q[i].v].sum;
}
else
{
if(findroot(q[i].u)!=findroot(q[i].v))
link(q[i].u,q[i].ans+n),link(q[i].v,q[i].ans+n);
else split(q[i].u,q[i].v),putly(q[i].v);
}
}
for(int i=1;i<=tot;++i)
if(q[i].opt)printf("%d\n",q[i].ans);
return 0;
}

【BZOJ1969】航线规划(Link-Cut Tree)的更多相关文章

  1. Link Cut Tree 总结

    Link-Cut-Tree Tags:数据结构 ##更好阅读体验:https://www.zybuluo.com/xzyxzy/note/1027479 一.概述 \(LCT\),动态树的一种,又可以 ...

  2. link cut tree 入门

    鉴于最近写bzoj还有51nod都出现写不动的现象,决定学习一波厉害的算法/数据结构. link cut tree:研究popoqqq那个神ppt. bzoj1036:维护access操作就可以了. ...

  3. Codeforces Round #339 (Div. 2) A. Link/Cut Tree 水题

    A. Link/Cut Tree 题目连接: http://www.codeforces.com/contest/614/problem/A Description Programmer Rostis ...

  4. Link/cut Tree

    Link/cut Tree 一棵link/cut tree是一种用以表示一个森林,一个有根树集合的数据结构.它提供以下操作: 向森林中加入一棵只有一个点的树. 将一个点及其子树从其所在的树上断开. 将 ...

  5. 洛谷P3690 Link Cut Tree (模板)

    Link Cut Tree 刚开始写了个指针版..调了一天然后放弃了.. 最后还是学了黄学长的板子!! #include <bits/stdc++.h> #define INF 0x3f3 ...

  6. LCT总结——概念篇+洛谷P3690[模板]Link Cut Tree(动态树)(LCT,Splay)

    为了优化体验(其实是强迫症),蒟蒻把总结拆成了两篇,方便不同学习阶段的Dalao们切换. LCT总结--应用篇戳这里 概念.性质简述 首先介绍一下链剖分的概念(感谢laofu的讲课) 链剖分,是指一类 ...

  7. bzoj2049 [Sdoi2008]Cave 洞穴勘测 link cut tree入门

    link cut tree入门题 首先说明本人只会写自底向上的数组版(都说了不写指针.不写自顶向下QAQ……) 突然发现link cut tree不难写... 说一下各个函数作用: bool isro ...

  8. P3690 【模板】Link Cut Tree (动态树)

    P3690 [模板]Link Cut Tree (动态树) 认父不认子的lct 注意:不 要 把 $fa[x]$和$nrt(x)$ 混 在 一 起 ! #include<cstdio> v ...

  9. Link Cut Tree学习笔记

    从这里开始 动态树问题和Link Cut Tree 一些定义 access操作 换根操作 link和cut操作 时间复杂度证明 Link Cut Tree维护链上信息 Link Cut Tree维护子 ...

随机推荐

  1. html中meta标签及用法理解

    自己一直想成为高级前端开发工程师,而自学.奈何最近感觉自学收效甚微,一度迷茫. 不破不立,打算改变这样的状态. 春节后上班第一天,今年打算好好实现自己的前端梦想. 重新整理.总结前端技术. 废话,就不 ...

  2. ps通道抠章

    1. 打开图片 2. 使用椭圆形选框工具,选择章所在范围(ALT+SHITF+鼠标左键) 3.复制图层(CTRL+J)为图层1,隐藏背景 4.进入通道,选择对比度最大的通道,复制通道副本 5.反选(C ...

  3. 关于 iOS 分类(Category)的实现代码

    其实质是对一个类的扩充,对类扩充的方法有两种: (1)通过继承(经常用到) (2)通过分类 一个已知类Name 其头文件Name.h #import <Foundation/Foundation ...

  4. 对html语义化的理解

    所有人都知道html即超文本标记语言或超文本链接标示语言,是目前网络上应用最为广泛的语言,也是构成网页文档的主要语言. html标签中的大部分都是由"语义化"标签所担任 那么,它有 ...

  5. [bzoj2286][Sdoi 2011]消耗战

    [bzoj2286]消耗战 标签: 虚树 DP 题目链接 题解 很容易找出\(O(mn)\)的做法. 只需要每次都dp一遍. 但是m和n是同阶的,所以这样肯定会T的. 注意到dp的时候有很多节点是不需 ...

  6. LaTeX 各种命令,符号

    函数.符号及特殊字符 声调 语法 效果 语法 效果 语法 效果 \bar{x} \acute{\eta} \check{\alpha} \grave{\eta} \breve{a} \ddot{y} ...

  7. jquery序列化serialize()方法空格变为+问题解决参考方法

    $("#sendNoticeData-form").serialize();会在value中存在空格的地方转化为+符合.比如:name:tiwax aaa序列化后为tiwax+aa ...

  8. Thymeleaf入门基础

    一.简介 1.thymeleaf优点 ①是一个支持html原型的自然引擎,它在html标签增加额外的属性来达到模板+数据的展示方式,由于浏览器解释html时,忽略未定义的标签属性,因此thymelea ...

  9. js在函数中未定义的变量的处理

    <html> <head> <script type="text/javascript"> var z=1; function abc(){ x ...

  10. API token for Github

    1.如图所示:(前提是登录Github,进入Personal settings) 2,创建token 3,生成token 4. Last login: Mon Dec  5 20:24:18 on c ...