【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 题目大意:有一天,由于某 ...
随机推荐
- js事件的机制
1.html事件处理程序 <button id="btn1" onclick="alert(1);">按钮1</button> 2.do ...
- 日常踩坑——rand()总是出现重复数据
写了一个生成随机数组的函数,然后跑出来,结果总是…… 然后,很奇怪的是一步一步调试,它就没问题了,WTF??? 问题出在:重复写了srand(time(NULL)),只保留一个就好了. int* ge ...
- [Java123] JDBC and Multi-Threading 多线程编程学习笔记
项目实际需求:DB交互使用多线程实现 多线程编程基础:1.5 :( (假设总分10) 计划一个半月从头学习梳理Java多线程编程基础以及Oracle数据库交互相关的多线程实现 学习如何通过代码去验证 ...
- 如何批量下载bing的背景图片?
工具准备 wget(点击下载) 批处理命令(点击下载) 网友提供的接口:http://area.sinaapp.com/bingImg?daysAgo=1(1代表天数) 实现步骤 1.打开记事本,并将 ...
- wireMock快速伪造restful服务
官网地址:http://wiremock.org/ Jar下载:http://repo1.maven.org/maven2/com/github/tomakehurst/wiremock/1.57/w ...
- Gradle Goodness: Run a Build Script With a Different Name
Normally Gradle looks for a build script file with the name build.gradle in the current directory to ...
- 3.高并发教程-基础篇-之分布式全文搜索引擎elasticsearch的搭建
高并发教程-基础篇-之分布式全文搜索引擎elasticsearch的搭建 如果大家看了我的上一篇<2.高并发教程-基础篇-之nginx+mysql实现负载均衡和读写分离>文章,如果能很好的 ...
- case when then else end 与 decode 的区别
case when then else end : 条件可以有 等于 ,大于 ,小于 与 decode : 条件只可以有等于的.
- PyCharm 2018最新激活码通用
通用:Window.Mac.Ubantu都稳定有效,关键是这种激活方式不会产生其他影响 缺点:需要修改hosts文件 **1.修改hosts文件**将 0.0.0.0 account.jetbrain ...
- 高性能MySQL--创建高性能的索引
关于MySQL的优化,相信很多人都听过这一条:避免使用select *来查找字段,而是要在select后面写上具体的字段. 那么这么做的原因相信大家都应该知道:减少数据量的传输. 但我要讲的是另外一个 ...