【BZOJ1018】[SHOI2008]堵塞的交通

题面

bzoj

洛谷

洛谷

题解

菊队讲要用线段树维护连通性,但是好像没人写

解法一

将所有的加边删边离线,然后以最近删除时间为边权,$LCT$维护最大生成树即可

代码

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <cmath>
#include <algorithm>
#include <map>
using namespace std;
inline int gi() {
register int data = 0, w = 1;
register char ch = 0;
while (!isdigit(ch) && ch != '-') ch = getchar();
if (ch == '-') w = -1, ch = getchar();
while (isdigit(ch)) data = 10 * data + ch - '0', ch = getchar();
return w * data;
}
const int MAX_N = 100005;
const int INF = 1e9;
struct Node { int fa, ch[2], v, d; bool rev; } t[MAX_N << 2];
int stk[MAX_N << 2], top;
void pushup(int x) {
t[x].d = x;
if (t[t[x].d].v > t[t[t[x].ch[0]].d].v) t[x].d = t[t[x].ch[0]].d;
if (t[t[x].d].v > t[t[t[x].ch[1]].d].v) t[x].d = t[t[x].ch[1]].d;
}
void pushrev(int x) {
t[x].rev ^= 1;
swap(t[x].ch[0], t[x].ch[1]);
}
void pushdown(int x) {
if (!t[x].rev) return ;
if (t[x].ch[0]) pushrev(t[x].ch[0]);
if (t[x].ch[1]) pushrev(t[x].ch[1]);
t[x].rev = 0;
}
int get(int x) { return t[t[x].fa].ch[1] == x; }
bool isroot(int x) { return (t[t[x].fa].ch[1] != x) && (t[t[x].fa].ch[0] != x); }
void rotate(int x) {
int k = get(x), y = t[x].fa, z = t[y].fa;
if (!isroot(y)) t[z].ch[get(y)] = x;
t[x].fa = z;
t[t[x].ch[k ^ 1]].fa = y, t[y].ch[k] = t[x].ch[k ^ 1];
t[x].ch[k ^ 1] = y, t[y].fa = x;
pushup(y), pushup(x);
}
void splay(int x) {
stk[top = 1] = x;
for (int i = x; !isroot(i); i = t[i].fa) stk[++top] = t[i].fa;
for (int i = top; i; i--) pushdown(stk[i]);
while (!isroot(x)) {
int y = t[x].fa;
if (!isroot(y)) (get(x) ^ get(y)) ? rotate(x) : rotate(y);
rotate(x);
}
}
void access(int x) { for (int y = 0; x; y = x, x = t[x].fa) splay(x), t[x].ch[1] = y, pushup(x); }
int findroot(int x) { access(x); splay(x); while (t[x].ch[0]) pushdown(x), x = t[x].ch[0]; return x; }
void makeroot(int x) { access(x); splay(x); pushrev(x); }
void split(int x, int y) { makeroot(x); access(y); splay(y); }
void link(int x, int y) { makeroot(x); t[x].fa = y; }
void cut(int x, int y) { split(x, y); t[y].ch[0] = t[x].fa = 0, pushup(y); }
int N, C, tot;
struct Opt { int t, op, x1, x2, del; } a[MAX_N << 1];
map<pair<int, int>, int> mp; int main () {
#ifndef ONLINE_JUDGE
freopen("cpp.in", "r", stdin);
freopen("cpp.out", "w", stdout);
#endif
C = gi();
for ( ; ; ) {
char ch[10]; scanf("%s", ch);
if (ch[0] == 'E') break;
int op, r1 = gi() - 1, c1 = gi(), r2 = gi() - 1, c2 = gi(), x1 = r1 * C + c1, x2 = r2 * C + c2;
if (x1 > x2) swap(x1, x2);
if (ch[0] == 'O') op = 0;
if (ch[0] == 'C') op = 1;
if (ch[0] == 'A') op = 2;
++N;
if (op == 0) mp[pair<int, int>(x1, x2)] = N, a[N].del = INF;
if (op == 1) a[mp[pair<int, int>(x1, x2)]].del = N;
a[N].t = N, a[N].op = op, a[N].x1 = x1, a[N].x2 = x2;
}
tot = 2 * C;
for (int i = 0; i <= tot; i++) t[i].v = INF;
for (int i = 1; i <= N; i++) {
int x1 = a[i].x1, x2 = a[i].x2, del = a[i].del;
if (a[i].op == 0) {
if (findroot(x1) == findroot(x2)) {
split(x1, x2); int d = t[x2].d;
if (t[d].v >= del) continue;
else cut(x1, d), cut(x2, d);
t[++tot].v = del;
link(x1, tot), link(x2, tot);
}
else t[++tot].v = del, link(x1, tot), link(x2, tot);
}
if (a[i].op == 1)
if (findroot(x1) == findroot(x2)) {
split(x1, x2);
int d = t[x2].d;
if (t[d].v > a[i].t) continue;
cut(x1, d), cut(x2, d);
}
if (a[i].op == 2) {
if (findroot(x1) == findroot(x2)) puts("Y");
else puts("N");
}
}
return 0;
}

解法二

没打,但是可以参考这篇文章

【BZOJ1018】[SHOI2008]堵塞的交通的更多相关文章

  1. [bzoj1018][SHOI2008]堵塞的交通traffic_线段树

    bzoj-1018 SHOI-2008 堵塞的交通traffic 参考博客:https://www.cnblogs.com/MashiroSky/p/5973686.html 题目大意:有一天,由于某 ...

  2. bzoj千题计划108:bzoj1018: [SHOI2008]堵塞的交通traffic

    http://www.lydsy.com/JudgeOnline/problem.php?id=1018 关键点在于只有两行 所以一个2*m矩形连通情况只有6种 编号即对应代码中的a数组 线段树维护 ...

  3. [BZOJ1018][SHOI2008]堵塞的交通traffic 线段树维护连通性

    1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec  Memory Limit: 162 MB Submit: 3795  Solved: 1253 [Sub ...

  4. BZOJ1018 [SHOI2008]堵塞的交通traffic

    本文版权归ljh2000和博客园共有,欢迎转载,但须保留此声明,并给出原文链接,谢谢合作. 本文作者:ljh2000作者博客:http://www.cnblogs.com/ljh2000-jump/转 ...

  5. BZOJ1018[SHOI2008]堵塞的交通——线段树

    题目描述 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总 ...

  6. [bzoj1018] [SHOI2008]堵塞的交通

    题目描述 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个22行CC列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所 ...

  7. 【离线 撤销并查集 线段树分治】bzoj1018: [SHOI2008]堵塞的交通traffic

    本题可化成更一般的问题:离线动态图询问连通性 当然可以利用它的特殊性质,采用在线线段树维护一些标记的方法 Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常 ...

  8. 【线段树】bzoj1018 [SHOI2008]堵塞的交通traffic

    线段树的每个叶子节点存一列. 每个节点维护六个域,分别是左上左下.左上右上.左上右下.左下右上.左下右下.右上右下在区间内部的连通性,不考虑绕出去的情况. 初始每个叶子的左上左下.右上右下是连通的. ...

  9. BZOJ1018 SHOI2008堵塞的交通(线段树)

    动态图的连通性当然是可以用LCT维护的.但这相当的不优美,毕竟这样做没有用到任何该图的性质,LCT自带的大常数也会使其跑得非常慢. 考虑用线段树维护区间左右端四个点之间各自的连通性(仅经过该区间内路径 ...

  10. Bzoj1018[SHOI2008]堵塞的交通traffic(线段树)

    这题需要维护连通性,看到有连接删除,很容易直接就想LCT了.然而这题点数20w操作10w,LCT卡常估计过不去.看到这个东西只有两行,考虑能否用魔改后的线性数据结构去维护.我想到了线段树. 考虑如果两 ...

随机推荐

  1. asp.net使用一般处理程序实现文件下载

    首先有一个html页面,页面有一个链接,点击链接弹出文件下载/保存(类似迅雷下载链接) <!DOCTYPE html> <html> <head> <meta ...

  2. django项目设计

    我们以前是只建立一个项目只建立一个app,如果我们要建立多个app的时候 并且这个app要写很多额视图的函数views内函数,要是建立很多种的时候就会造成很冗杂,不美观  我们未来增强解耦性,就把那个 ...

  3. [翻译] OCMaskedTextField

    OCMaskedTextField https://github.com/OmerCora/OCMaskedTextField Simple class to display dynamically ...

  4. [翻译] CHTCollectionViewWaterfallLayout

    CHTCollectionViewWaterfallLayout https://github.com/chiahsien/CHTCollectionViewWaterfallLayout CHTCo ...

  5. Python(二)列表的增删改查

    一,列表的增删改查 列表中增加元素: 1,从列表的末尾增加一个元素:append("") 2,从列表中插入一个元素:insert(下标位置,插入的元素) 合并列表: 1,name. ...

  6. 关于WSL(Windows上的Linux子系统)的简单介绍及安装

    WSL,Windows Subsystem for Linux,就是之前的Bash on [Ubuntu on] Windows(嗯,微软改名部KPI++),在wsl环境下我们可以运行一些Linux程 ...

  7. September 07th 2017 Week 36th Thursday

    With the most true of yourself, can you meet the most suitable one. 用最真实的自己,才能遇见最合适的那个人. You are alw ...

  8. ZT eoe android4.2 Bluetooth记录01-结构和代码分布

    android4.2 Bluetooth记录01-结构和代码分布 作者:cnhua5更新于 08月21日访问(697)评论(2) 在android4.2中,Google更换了android的蓝牙协议栈 ...

  9. Python中网络编程对socket accept函数的理解

    在服务器端,socket()返回的套接字用于监听(listen)和接受(accept),这个套接字不能用于与客户端之间发送和接收数据. accept()接受一个客户端的连接请求,并返回一个新的套接字, ...

  10. Ceph块存储介绍

    1. 块存储是什么 块存储简称RBD(RADOS Block Device),是一种有序的字节序块,也是在Ceph三大存储类型中最为常用的存储方式 ,Ceph的块存储是基于RADOS的,因此它也借助R ...