线段树分治+并查集

线段树本身就是分治结构,碰见这种带删除修改的题目是再合适不过的,我们对于每段修改区间在线段树上打标记,每次路过就进行修改,叶子结点表及答案,先把所有修改在线段树上标记,然后dfs就行了

但是并查集怎么恢复呢?我们只要维护一个栈,保存某次操作之前这两个点的信息,dfs本身就是利用栈来操作,那么每次回溯就用栈的信息恢复之前的样子就行了

#include<bits/stdc++.h>
using namespace std;
const int N = ;
int c, tot, cnt, top, ask;
int fa[N], l[N], r[N], d[N], mark[N];
bool ans[N];
struct dsu {
int u, v, fa, du, dv;
dsu(int u = , int v = , int fa = , int du = , int dv = ) : u(u), v(v), fa(fa), du(du), dv(dv) {}
} st[N];
pair<int, int> operation[N];
map<pair<int, int>, int> mp;
vector<pair<int, int> > tree[N << ], q[N << ];
char opt[];
inline int read()
{
int x = , f = ; char c = getchar();
while(c < '' || c > '') { if(c == '-') f = -; c = getchar(); }
while(c >= '' && c <= '') { x = x * + c - ''; c = getchar(); }
return x * f;
}
int find(int x)
{
return x == fa[x] ? x : find(fa[x]);
}
int id(int x, int y)
{
return (x - ) * c + y;
}
void unite(pair<int, int> o)
{
int x = find(o.first), y = find(o.second);
if(d[x] > d[y]) swap(x, y);
st[++top] = dsu(x, y, fa[x], d[x], d[y]);
if(x != y)
{
d[y] += d[x];
fa[x] = y;
}
}
void del(int now)
{
while(top != now)
{
dsu x = st[top];
fa[x.u] = x.fa;
d[x.u] = x.du;
d[x.v] = x.dv;
--top;
}
}
void update(int l, int r, int x, int a, int b, pair<int, int> o)
{
if(l > b || r < a) return;
if(l >= a && r <= b)
{
tree[x].push_back(o);
return;
}
int mid = (l + r) >> ;
update(l, mid, x << , a, b, o);
update(mid + , r, x << | , a, b, o);
}
void dfs(int l, int r, int x)
{
int now = top;
for(int i = ; i < tree[x].size(); ++i) unite(tree[x][i]);
if(l == r)
{
for(int i = ; i < q[l].size(); ++i)
{
pair<int, int> o = q[l][i];
if(find(o.first) == find(o.second)) puts("Y");
else puts("N");
}
del(now);
return;
}
int mid = (l + r) >> ;
dfs(l, mid, x << );
dfs(mid + , r, x << | );
del(now);
}
int main()
{
// freopen("bzoj_1018.in", "r", stdin);
// freopen("bzoj_1018.out", "w", stdout);
memset(l, 0x3f3f, sizeof(l));
c = read();
for(int i = ; i <= * c; ++i)
{
fa[i] = i;
d[i] = ;
}
while(scanf("%s", opt))
{
if(opt[] == 'E') break;
++tot;
int r1 = read(), c1 = read(), r2 = read(), c2 = read(), u = id(r1, c1), v = id(r2, c2);
if(u > v) swap(u, v);
if(opt[] == 'O')
{
if(mp.find(make_pair(u, v)) != mp.end()) continue;
l[++cnt] = tot;
operation[cnt] = make_pair(u, v);
mp[make_pair(u, v)] = cnt;
}
if(opt[] == 'C')
{
if(mp.find(make_pair(u, v)) == mp.end()) continue;
r[mp[make_pair(u, v)]] = tot - ;
mp.erase(make_pair(u, v));
}
if(opt[] == 'A') q[tot].push_back(make_pair(u, v));
}
for(int i = ; i <= cnt; ++i)
{
if(!r[i]) r[i] = tot;
update(, tot, , l[i], r[i], operation[i]);
}
dfs(, tot, );
for(int i = ; i <= ask; ++i) if(ans[i]) puts("Y");
else puts("N");
// fclose(stdin);
// fclose(stdout);
return ;
}

bzoj1018的更多相关文章

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

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

  2. 【bzoj1018】 SHOI2008—堵塞的交通traffic

    http://www.lydsy.com/JudgeOnline/problem.php?id=1018 (题目链接) 题意 一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道 ...

  3. 【bzoj1018】堵塞的交通

    [bzoj1018]堵塞的交通 题意 一个\(2*n\)的格子,相邻格子之间有一条道路.初始时道路是不通的. \(C\)个操作,每个操作为三种中的一种:(1)某条道路连起来:(2)某条道路断开:(3) ...

  4. 【BZOJ1018】堵塞的交通(线段树)

    [BZOJ1018]堵塞的交通(线段树) 题面 Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可 以被看成是一个2行C列的矩形网 ...

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

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

  6. 【BZOJ1018】[SHOI2008]堵塞的交通

    [BZOJ1018][SHOI2008]堵塞的交通 题面 bzoj 洛谷 洛谷 题解 菊队讲要用线段树维护连通性,但是好像没人写 解法一 将所有的加边删边离线,然后以最近删除时间为边权,$LCT$维护 ...

  7. 【BZOJ1018】[SHOI2008]堵塞的交通traffic 线段树

    [BZOJ1018][SHOI2008]堵塞的交通traffic Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个 ...

  8. 【BZOJ1018】堵塞的交通traffic(线段树,网格图,连通性)

    题意:一个2行C列的矩形网格图,网格上的每个点代表一个城市,相邻的城市之间有一条道路 一开始每条道路都是堵塞的,堵塞即为不可经过.经过一些操作后,可能某些道路通畅了,也可能某些道路堵塞了 多次询问,询 ...

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

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

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

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

随机推荐

  1. IMDB电影排行爬取分析

    一.打开IMDB电影T250排行可以看见250条电影数据,电影名,评分等数据都可以看见 按F12进入开发者模式,找到这些数据对应的HTML网页结构,如下所示 可以看见里面有链接,点击链接可以进入电影详 ...

  2. 13Microsoft SQL Server SQL 高级事务,锁,游标,分区

    Microsoft SQL Server SQL高级事务,锁,游标,分区 通过采用事务和锁机制,解决了数据库系统的并发性问题. 9.1数据库事务 (1)BEGIN TRANSACTION语句定义事务的 ...

  3. ListView常用属性 (2012-01-12 17:20:27)

    比较特别的属性,通过设置这样的属性可以做出更加美观的列表.stackFromBottom——设置该属性之后你最新条目就会显示你列表的最下面,值为true和false,如android:stackFro ...

  4. swift中使用对象归档进行数据本地

    对象归档是ios持久化中的其中一种,也是很常用的一种.现在来看看swift是如何实现的.实现要点1),必须实现NSCoding的协议 import UIKit let path=(NSSearchPa ...

  5. input file 美化的方法

    css input[type=file] 样式美化,input上传按钮美化 2014年8月29日 113210次浏览 由于明天公司组织出去游玩,今天把这两天的博客都写了吧,今天的内容是input[ty ...

  6. Gym - 101670B Pond Cascade(CTU Open Contest 2017 贪心,二分)

    题目: The cascade of water slides has been installed in the park recently and it has to be tested. The ...

  7. Java控制台读写

    Java控制台读写 控制台读 Java中进行控制台读操作主要是通过Scanner,BufferReader,Console类进行 1. Scanner Scanner对象定义 在控制台 Scanner ...

  8. LightOJ 1348 Aladdin and the Return Journey

    Aladdin and the Return Journey Time Limit: 2000ms Memory Limit: 32768KB This problem will be judged ...

  9. nyoj 1112 求次数(map, set)

    求次数 时间限制:1000 ms  |  内存限制:65535 KB 难度:2   描述 题意很简单,给一个数n 以及一个字符串str,区间[i,i+n-1] 为一个新的字符串,i 属于[0,strl ...

  10. Android layer-list(1)

     Android layer-list(1) Android layer-list,顾名思义,实现列表组合后形成的图层,写一个例子. activity_main.xml文件: <?xml v ...