【SHOI2008】堵塞的交通
题面
题解
这里提供几种不用脑子的算法(当然是离线的):
$\text{LCT}$
记下每条边的删除时间,用$\text{LCT}$维护最大生成树,每次加进一条边时,跟原来那条链上的做比较,删除那条删除时间最短的边即可。
线段树分治
这个算法将每条边的加入和删除时间加入到线段树中,所以在遍历到叶子节点时,那个时刻存在的边都已经在并查集上了,于是直接判断即可。
并查集用按秩合并就可以了,撤销时记得按栈序撤销。
代码
LCT
找$hyj$去
线段树分治
我的写法可能(比较好看)并没有建线段树......
#include<cstdio>
#include<cstring>
#include<cctype>
#include<algorithm>
#include<vector>
#include<map>
#define RG register
#define clear(x, y) memset(x, y, sizeof(x))
inline int read()
{
int data = 0, w = 1; char ch = getchar();
while(ch != '-' && (!isdigit(ch))) ch = getchar();
if(ch == '-') w = -1, ch = getchar();
while(isdigit(ch)) data = data * 10 + (ch ^ 48), ch = getchar();
return data * w;
}
const int maxn(200010);
struct edge { int from, to, beg, end; };
std::pair<int, int> q[maxn], stk[maxn << 2];
std::vector<edge> e;
std::map<int, int> G[maxn];
int fa[maxn], top, q_num, n, id[2][maxn], cnt, size[maxn];
char s[10];
inline int find(int x) { while(x ^ fa[x]) x = fa[x]; return x; }
inline void merge(int x, int y)
{
int fx = find(x), fy = find(y);
if(fx == fy) return;
if(size[fx] > size[fy]) std::swap(fx, fy);
fa[fx] = fy; size[fy] += size[fx]; stk[++top] = std::make_pair(fx, fy);
}
inline void undo()
{
int x = stk[top].first, y = stk[top--].second;
fa[x] = x; size[y] -= size[x];
}
inline void Div(int l, int r, std::vector<edge> E)
{
std::vector<edge> L, R;
std::vector<edge>::iterator it;
int mid = (l + r) >> 1, tmp = top;
for(it = E.begin(); it != E.end(); ++it)
if(it -> beg <= l && r <= it -> end) merge(it -> from, it -> to);
else
{
if(it -> beg <= mid) L.push_back(*it);
if(it -> end > mid) R.push_back(*it);
}
if(l == r) printf("%c\n", find(q[l].first) == find(q[l].second) ? 'Y' : 'N');
else Div(l, mid, L), Div(mid + 1, r, R);
while(top > tmp) undo();
}
int main()
{
n = read();
for(RG int i = 1; i <= n; i++)
id[0][i] = ++cnt, id[1][i] = ++cnt;
for(RG int r1, c1, r2, c2;;)
{
scanf("%s", s);
if(s[0] == 'E') break;
r1 = read() - 1, c1 = read(), r2 = read() - 1, c2 = read();
if(s[0] == 'O')
{
e.push_back((edge){id[r1][c1], id[r2][c2], q_num + 1, -1});
G[id[r1][c1]][id[r2][c2]] = G[id[r2][c2]][id[r1][c1]] = e.size() - 1;
}
else if(s[0] == 'C') e[G[id[r1][c1]][id[r2][c2]]].end = q_num;
else if(s[0] == 'A') q[++q_num] = std::make_pair(id[r1][c1], id[r2][c2]);
}
for(std::vector<edge>::iterator it = e.begin(); it != e.end(); ++it)
if(it -> end == -1) it -> end = q_num;
for(RG int i = 1; i <= n + n; i++) fa[i] = i, size[i] = 1;
Div(1, q_num, e);
return 0;
}
【SHOI2008】堵塞的交通的更多相关文章
- 数据结构(线段树):BZOJ 1018: [SHOI2008]堵塞的交通traffic
1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 2638 Solved: 864 Descri ...
- BZOJ 1018 [SHOI2008]堵塞的交通traffic
1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 2247 Solved: 706[Submit ...
- BZOJ 1018: [SHOI2008]堵塞的交通traffic [线段树 区间信息]
1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 3064 Solved: 1027[Submi ...
- bzoj千题计划108:bzoj1018: [SHOI2008]堵塞的交通traffic
http://www.lydsy.com/JudgeOnline/problem.php?id=1018 关键点在于只有两行 所以一个2*m矩形连通情况只有6种 编号即对应代码中的a数组 线段树维护 ...
- 【BZOJ1018】[SHOI2008]堵塞的交通
[BZOJ1018][SHOI2008]堵塞的交通 题面 bzoj 洛谷 洛谷 题解 菊队讲要用线段树维护连通性,但是好像没人写 解法一 将所有的加边删边离线,然后以最近删除时间为边权,$LCT$维护 ...
- 1018: [SHOI2008]堵塞的交通traffic
1018: [SHOI2008]堵塞的交通traffic 链接 分析: 用线段树维护区间的四个端点的联通情况,然后查询的时候,把所有覆盖到的区间合并起来即可. 六种情况左上到右上(左边到右边的情况)… ...
- 【bzoj1018】[SHOI2008]堵塞的交通traffic
1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 2887 Solved: 954[Submit ...
- [BZOJ1018][SHOI2008]堵塞的交通traffic 线段树维护连通性
1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec Memory Limit: 162 MB Submit: 3795 Solved: 1253 [Sub ...
- 【BZOJ1018】[SHOI2008]堵塞的交通traffic 线段树
[BZOJ1018][SHOI2008]堵塞的交通traffic Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个 ...
- [bzoj1018][SHOI2008]堵塞的交通traffic_线段树
bzoj-1018 SHOI-2008 堵塞的交通traffic 参考博客:https://www.cnblogs.com/MashiroSky/p/5973686.html 题目大意:有一天,由于某 ...
随机推荐
- What Shape Layers Are-CAShapeLayer
矢量图.gpu直接使用.占用内存小 What Shape Layers Are Shape layers are layers capable of defining shapes as vector ...
- 【[APIO2010]巡逻】
\(APIO\)的题就是非常难啊 首先看到\(k=1\)的情况,显然我们只需要找到一条直径把这条直径的两端连起来就好了 因为我们连这一条新边的实质是使得这一条链上的边不需要重复经过了,我们想让走的边尽 ...
- ubuntu ibus 输入法总在左下角不跟随光标的处理
sudo apt-get install ibus-gtk ibus-gtk3 ibus-qt4 参考文章
- linq注意错误
使用EntityFramework6连接MySql数据库(db first方式) 准备工具: VS2013.MySQL For VisualStudio 1.1.4.Connector/Net 6.8 ...
- LayIM.AspNetCore Middleware 开发日记(四)主角登场(LayIM介绍)
前言 在前几篇中已经初步介绍了开发AspNetCore中间件的一些基础知识,不过都没有很深入的去研究,后续还是需要去看看源码.本篇呢,终于有点开头的味道了,就是要介绍LayIM了,其实标题写的是主角, ...
- 洛谷P1832 A+B Problem(再升级)
放题解 题目传送门 放代码 #include<bits/stdc++.h> using namespace std; ];//n为被分解数 a数组用于存储素数 ];//dp数组用于存储方案 ...
- PHP面试系列之Linux(一) ----- Linux基础
一.系统安全 sudo:以系统管理者的身份执行指令,也就是说,经由 sudo 所执行的指令就好像是 root 亲自执行. su:用于变更为其他使用者的身份,除 root 外,需要键入该使用者的密码. ...
- ActiveRecord初始化,可以实现jfinal系统启动完成后,再建立数据库连接
1.JFinalConfig的afterJFinalStart方法,可以实现系统启动成功后,调用的方法 2.ActiveRecord 多数据源初始化 package com.meiah.common; ...
- vue04-动画、组件
一.vue中使用动画 文档:https://cn.vuejs.org/v2/guide/transitions.html 1. Vue 中的过渡动画 <!DOCTYPE html> < ...
- mysql将日期字符串转换
举个例子: 给定字符串为07/31/2018,想要把格式转换成20180731 需要用到以下两个函数: date_format(date,’%Y-%m-%d’) ————–>oracle中的to ...