BZOJ 1018|SHOI 2008|堵塞的交通|线段树
2016-04-21 21:07
316 查看
咦,一道自带题解的题目?
题目的坐标表示成(r,c),r=row,行号,c=column,列号。
因此x1,x2只有取1和2两种情况………
考虑线段树维护一格的连通性,合并区间如图:
令总的为r,左半区间a,右半区间b,修改了mid(x,y)。
那么对于r0(上);r1(下);r2(左);r3(右);r4(右下);r5(右上)有:
r_0=a_0&x&b_0|a_4&y&b_5
r_1=a_1&x&b_1|a_5&y&b_3
r_2=a_2|a_0&x&b_2&y&a_1
r_3=a_3|b_0&x&a_3&y&b_1
r_4=a_0&x&b_4|a_4&y&b_1
r_5=a_5&x&b_0|a_1&y&b_5
那么线段树的节点就这么维护这6个值。
x和y就是线段中点的上下边情况。
修改的时候,如果是修改横边,若要修改的就是横跨两子区间的横边,那么就可以直接维护了。如果是修改竖边,若当前区间已经变成一个点,那么直接维护即可。
否则分解区间。
对于查询,注意会有先往两边走再往中间走的情况,因此我们查询要查询左边,当前和右边。查询取出线段后,按照维护的方法类似地判断即可。
orz http://blog.csdn.net/qq_20669971/article/details/50805782 的简洁代码,大家一起%%%
Submit: 2655 Solved: 877
[Submit][Status][Discuss]
以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个
城市和3C-2条道路。 小人国的交通状况非常槽糕。有的时候由于交通堵塞,两座城市之间的道路会变得不连通,
直到拥堵解决,道路才会恢复畅通。初来咋到的你决心毛遂自荐到交通部某份差事,部长听说你来自一个科技高度
发达的世界,喜出望外地要求你编写一个查询应答系统,以挽救已经病入膏肓的小人国交通系统。 小人国的交通
部将提供一些交通信息给你,你的任务是根据当前的交通情况回答查询的问题。交通信息可以分为以下几种格式:
Close r1 c1 r2 c2:相邻的两座城市(r1,c1)和(r2,c2)之间的道路被堵塞了;Open r1 c1 r2 c2:相邻的两座城
市(r1,c1)和(r2,c2)之间的道路被疏通了;Ask r1 c1 r2 c2:询问城市(r1,c1)和(r2,c2)是否连通。如果存在一
条路径使得这两条城市连通,则返回Y,否则返回N;
结束。我们假设在一开始所有的道路都是堵塞的。我们保证 C小于等于100000,信息条数小于等于100000。
Open 1 1 1 2
Open 1 2 2 2
Ask 1 1 2 2
Ask 2 1 2 2
Exit
N
题目的坐标表示成(r,c),r=row,行号,c=column,列号。
因此x1,x2只有取1和2两种情况………
考虑线段树维护一格的连通性,合并区间如图:
令总的为r,左半区间a,右半区间b,修改了mid(x,y)。
那么对于r0(上);r1(下);r2(左);r3(右);r4(右下);r5(右上)有:
r_0=a_0&x&b_0|a_4&y&b_5
r_1=a_1&x&b_1|a_5&y&b_3
r_2=a_2|a_0&x&b_2&y&a_1
r_3=a_3|b_0&x&a_3&y&b_1
r_4=a_0&x&b_4|a_4&y&b_1
r_5=a_5&x&b_0|a_1&y&b_5
那么线段树的节点就这么维护这6个值。
x和y就是线段中点的上下边情况。
修改的时候,如果是修改横边,若要修改的就是横跨两子区间的横边,那么就可以直接维护了。如果是修改竖边,若当前区间已经变成一个点,那么直接维护即可。
否则分解区间。
对于查询,注意会有先往两边走再往中间走的情况,因此我们查询要查询左边,当前和右边。查询取出线段后,按照维护的方法类似地判断即可。
orz http://blog.csdn.net/qq_20669971/article/details/50805782 的简洁代码,大家一起%%%
#include <cstdio> #include <algorithm> using namespace std; const int N = 100005; #define id(i,j) ((i)*(n-1)+(j)) struct Node { bool w[6]; bool &operator[] (int a) { return w[a]; } } tree[N * 3], s[2]; int n, mp[N * 2]; void build(int t, int l, int r) { int mid = l + r >> 1; if (l == r) tree[t] = s[0]; else build(t * 2, l, mid), build(t * 2 + 1, mid + 1, r); } Node join(Node a, Node b, int mid) { Node r; bool x = mp[id(0, mid)], y = mp[id(1, mid)]; r[0] = a[0] && x && b[0] || a[4] && y && b[5]; r[1] = a[1] && y && b[1] || a[5] && x && b[4]; r[2] = a[2] || a[0] && x && b[2] && y && a[1]; r[3] = b[3] || b[0] && x && a[3] && y && b[1]; r[4] = a[0] && x && b[4] || a[4] && y && b[1]; r[5] = b[0] && x && a[5] || b[5] && y && a[1]; return r; } void modify(int t, int l, int r, int x1, int y1, int x2, int y2, bool c) { int mid = l + r >> 1, y = min(y1, y2); if (x1 == x2 && y == mid) { mp[id(x1, y)] = c; tree[t] = join(tree[t * 2], tree[t * 2 + 1], mid); } else if (x1 != x2 && l == r) tree[t] = s[c]; else { if (y <= mid) modify(t * 2, l, mid, x1, y1, x2, y2, c); if (y > mid) modify(t * 2 + 1, mid + 1, r, x1, y1, x2, y2, c); tree[t] = join(tree[t * 2], tree[t * 2 + 1], mid); } } Node query(int t, int l, int r, int ql, int qr) { int mid = l + r >> 1; if (ql <= l && r <= qr) return tree[t]; if (qr <= mid) return query(t * 2, l, mid, ql, qr); else if (mid < ql) return query(t * 2 + 1, mid + 1, r, ql, qr); else return join(query(t * 2, l, mid, ql, mid), query(t * 2 + 1, mid + 1, r, mid + 1, qr), mid); } bool ask(int x1, int y1, int x2, int y2) { if (y1 > y2) swap(x1, x2), swap(y1, y2); Node a = query(1, 1, n, y1, y2); Node b = query(1, 1, n, 1, y1); Node c = query(1, 1, n, y2, n); if (x1 == x2) return a[x1] || b[3] && a[4 + !x1] || c[2] && a[4 + x1] || b[3] && c[2] && a[!x1]; if (x1 != x2) return a[4 + x1] || b[3] && a[!x1] || c[2] && a[x1] || b[3] && c[2] && a[4 + !x1]; } int main() { int x1, y1, x2, y2, i; char op[8]; scanf("%d", &n); s[0] = (Node) { 1, 1, 0, 0, 0, 0 }; s[1] = (Node) { 1, 1, 1, 1, 1, 1 }; build(1, 1, n); while (scanf("%s", op), op[0] != 'E') { scanf("%d%d%d%d", &x1, &y1, &x2, &y2); --x1; --x2; if (op[0] == 'O') modify(1, 1, n, x1, y1, x2, y2, 1); if (op[0] == 'C') modify(1, 1, n, x1, y1, x2, y2, 0); if (op[0] == 'A') puts(ask(x1, y1, x2, y2) ? "Y" : "N"); } return 0; }
1018: [SHOI2008]堵塞的交通traffic
Time Limit: 3 Sec Memory Limit: 162 MBSubmit: 2655 Solved: 877
[Submit][Status][Discuss]
Description
有一天,由于某种穿越现象作用,你来到了传说中的小人国。小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个
城市和3C-2条道路。 小人国的交通状况非常槽糕。有的时候由于交通堵塞,两座城市之间的道路会变得不连通,
直到拥堵解决,道路才会恢复畅通。初来咋到的你决心毛遂自荐到交通部某份差事,部长听说你来自一个科技高度
发达的世界,喜出望外地要求你编写一个查询应答系统,以挽救已经病入膏肓的小人国交通系统。 小人国的交通
部将提供一些交通信息给你,你的任务是根据当前的交通情况回答查询的问题。交通信息可以分为以下几种格式:
Close r1 c1 r2 c2:相邻的两座城市(r1,c1)和(r2,c2)之间的道路被堵塞了;Open r1 c1 r2 c2:相邻的两座城
市(r1,c1)和(r2,c2)之间的道路被疏通了;Ask r1 c1 r2 c2:询问城市(r1,c1)和(r2,c2)是否连通。如果存在一
条路径使得这两条城市连通,则返回Y,否则返回N;
Input
第一行只有一个整数C,表示网格的列数。接下来若干行,每行为一条交通信息,以单独的一行“Exit”作为结束。我们假设在一开始所有的道路都是堵塞的。我们保证 C小于等于100000,信息条数小于等于100000。
Output
对于每个查询,输出一个“Y”或“N”。Sample Input
2Open 1 1 1 2
Open 1 2 2 2
Ask 1 1 2 2
Ask 2 1 2 2
Exit
Sample Output
YN
相关文章推荐
- 多线程编程之同步
- 通过adb从手机中导出安装包或导入
- C#入门经典(第6版)
- CodeForces - 554A Kyoya and Photobooks (水)
- 解决react-native run-android报DeviceException Could not create ADB Bridge错误
- 阶梯博弈(Staircase Nim)
- 矩阵--原地转置--面试题
- win10下什么拼音输入法好用
- 客户端js判断文件类型和文件大小即限制上传大小图片预览
- MQTT正式部署注意点
- 【转】HLSL基础
- if test
- Android基础:获取手机联系人工具类
- 笔记:配置父Activity
- c++map基本操作
- 最近进行Android移植以及NDK开发的编外心得
- 大一下学期第九周周记
- Android如何防止apk程序被反编译
- idea+tomcat+web项目 中tomcat的部署和运行
- crm操作产品实体