【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. MySQL Bug导致异常宕机的分析流程

    原文链接:http://click.aliyun.com/m/42521/ 摘要: 本文主要通过一个bug来记录一下如何分析一个MySQL bug的崩溃信息. 版本:Percona 5.7.17-11 ...

  2. 转:C# 线程同步技术 Monitor 和Lock

    原文地址:http://www.cnblogs.com/lxblog/archive/2013/03/07/2947182.html 今天我们总结一下 C#线程同步 中的 Monitor 类 和 Lo ...

  3. 简单解析Spring核心IOC容器原理

    将大体流程解析了一边,具体可以看源代码一个方法一个方法的跟下 XmlBeanFactory的功能是建立在DefaultListableBeanFactory这个基本容器的基础上的,并在这个基本容器的基 ...

  4. 用CHTCollectionViewWaterfallLayout写瀑布流

    用CHTCollectionViewWaterfallLayout写瀑布流 实现的瀑布流效果图: 源码: WaterfallCell.h 与 WaterfallCell.m // // Waterfa ...

  5. for 与forEach的区别

    for循环 for循环,通过下标,对循环中的代码反复执行,功能强大,可以通过index取得元素.在处理比较复杂的处理的时候较为方便. foreach循环 foreach,从头到尾,对于集合中的对象遍历 ...

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

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

  7. PHP设计模式系列 - 迭代器

    PHP迭代器: 可帮助构造特定的对象,那些对象能够提供单一标准接口循环或迭代任何类型的可计数数据.(不是特别常用,在PHP中) 使用场景: 1.访问一个聚合对象的内容而无需暴露它的内部表示. 2.支持 ...

  8. java内部类案例

    实现键值对的存储输出 import java.util.Arrays; public class EntryDemoTest { //实现键值对的存储 public static void main( ...

  9. ORA-28001: the password has expired (DBD ERROR: OCISessionBegin)解决办法

    1.问题描述: 打开oracle在线管理页面发现这个错误:界面如下 2问题原因 造成这个问题的主要原因是因为DBSNMP .SYSMAN用户密码已经过期. 3解决办法 可以使用sys以管理员的身份登录 ...

  10. 【[TJOI2015]弦论】

    \(SA+SAM\) 第一问显然是一个\(SAM\)的经典问题,我们排完序之后直接使用一直往下找\(n+1-sa[i]-het[i]\)就好了,找到\(K\)减不动了输出就好了 第二问是\(SAM\) ...