本题可化成更一般的问题:离线动态图询问连通性

当然可以利用它的特殊性质,采用在线线段树维护一些标记的方法

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”。


题目分析

这里提供一种更加一般的模型,即离线动态图连通性。

大体的思路是:把所有操作都离线之后,对询问分治,将每个询问看做线段树的一个节点(因为询问天然有序),并且记录当前剩余操作(可以是在过程里带vector)。那么这样在处理到每个叶子节点的时候,就已经把有关的操作都执行了。最后离开当前节点时,按栈序撤销并查集操作。

这个方法的时间复杂度是$O(m \log m \log n)$($\log n$是可撤销并查集的复杂度)。其优化的本质在于,让一段共用边的操作同时处理。

那么这里有一个很具有启发性的思路:对于一类询问$m$次,每次询问基于若干个元素的问题,可以通过离线分治的方式减少它们的冗余操作,将复杂度将为$O(m \log m \log n)$。当然最大的缺陷在于必须离线(而且过程里挂vector是不是太占空间了?)

  1. #include<bits/stdc++.h>
  2. const int maxn = ;
  3.  
  4. struct Edge
  5. {
  6. int u,v,s,t;
  7. Edge(int a=, int b=, int c=, int d=):u(a),v(b),s(c),t(d) {}
  8. };
  9. int n,qNum,top;
  10. int mp[][maxn],fat[maxn],size[maxn];
  11. typedef std::vector<Edge> vec;
  12. vec opt;
  13. std::map<int, int> tag[maxn];
  14. std::pair<int, int> qr[maxn],stk[maxn<<];
  15. char str[];
  16.  
  17. int read()
  18. {
  19. char ch = getchar();
  20. int num = , fl = ;
  21. for (; !isdigit(ch); ch=getchar())
  22. if (ch=='-') fl = -;
  23. for (; isdigit(ch); ch=getchar())
  24. num = (num<<)+(num<<)+ch-;
  25. return num*fl;
  26. }
  27. int find(int x)
  28. {
  29. while (x!=fat[x]) x = fat[x];
  30. return x;
  31. }
  32. void merge(int x, int y)
  33. {
  34. int fx = find(x), fy = find(y);
  35. if (size[fx] > size[fy]) std::swap(fx, fy);
  36. stk[++top] = std::make_pair(fx, fy);
  37. fat[fx] = fy, size[fy] += size[fx];
  38. }
  39. void cancel()
  40. {
  41. int x = stk[top].first, y = stk[top].second;
  42. fat[x] = x, size[y] -= size[x];
  43. }
  44. void solve(int l, int r, vec opt)
  45. {
  46. vec L,R;
  47. int mid = (l+r)>>, tmp = top;
  48. for (int i=, mx=opt.size(); i<mx; i++)
  49. {
  50. int s = opt[i].s, t = opt[i].t;
  51. if (s <= l&&r <= t) merge(opt[i].u, opt[i].v);
  52. else{
  53. if (s <= mid) L.push_back(opt[i]);
  54. if (t > mid) R.push_back(opt[i]);
  55. }
  56. }
  57. if (l==r) puts(find(qr[l].first)==find(qr[l].second)?"Y":"N");
  58. else solve(l, mid, L), solve(mid+, r, R);
  59. while (tmp!=top) cancel(), --top;
  60. }
  61. int main()
  62. {
  63. n = read();
  64. for (int i=, cnt=; i<=n; i++)
  65. mp[][i] = ++cnt, mp[][i] = ++cnt;
  66. for (int idx,idy; ;)
  67. {
  68. scanf("%s",str);
  69. if (str[]=='E') break;
  70. idx = mp[read()][read()], idy = mp[read()][read()];
  71. if (str[]=='O'){
  72. opt.push_back(Edge(idx, idy, qNum+, -));
  73. tag[idx][idy] = tag[idy][idx] = opt.size()-;
  74. }
  75. if (str[]=='C') opt[tag[idx][idy]].t = qNum;
  76. if (str[]=='A') qr[++qNum] = std::make_pair(idx, idy);
  77. }
  78. for (int i=, mx=opt.size(); i<mx; i++)
  79. if (opt[i].t==-) opt[i].t = qNum;
  80. for (int i=; i<=(n<<); i++) fat[i] = i, size[i] = ;
  81. solve(, qNum, opt);
  82. return ;
  83. }

END

【离线 撤销并查集 线段树分治】bzoj1018: [SHOI2008]堵塞的交通traffic的更多相关文章

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

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

  2. 【Codeforces576E_CF576E】Painting Edges(可撤销并查集+线段树分治)

    题目 CF576E 分析: 从前天早上肝到明天早上qwq其实颓了一上午MC ,自己瞎yy然后1A,写篇博客庆祝一下. 首先做这题之前推荐一道很相似的题:[BZOJ4025]二分图(可撤销并查集+线段树 ...

  3. 【BZOJ4025】二分图(可撤销并查集+线段树分治)

    题目: BZOJ4025 分析: 定理:一个图是二分图的充要条件是不存在奇环. 先考虑一个弱化的问题:保证所有边出现的时间段不会交叉,只会包含或相离. 还是不会?再考虑一个更弱化的问题:边只会出现不会 ...

  4. [BZOJ1018][SHOI2008]堵塞的交通traffic 线段树维护连通性

    1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec  Memory Limit: 162 MB Submit: 3795  Solved: 1253 [Sub ...

  5. [CSP-S模拟测试]:地理课(并查集+线段树分治)

    题目传送门(内部题146) 输入格式 从$geography.in$读入数据. 第一行两个数$n,m$,表示有$n$个点,$m$个时刻.接下来$m$行每行三个数,要么是$1\ u\ v$,要么是$2\ ...

  6. [BZOJ1018][SHOI2008]堵塞的交通traffic 时间分治线段树

    题面 介绍一种比较慢的但是好想的做法. 网上漫天的线段树维护联通性,然后想起来费很大周折也很麻烦.我的做法也是要用线段树的,不过用法完全不同. 这个东西叫做时间分治线段树. 首先我们建一个\(1..m ...

  7. Bzoj1018[SHOI2008]堵塞的交通traffic(线段树)

    这题需要维护连通性,看到有连接删除,很容易直接就想LCT了.然而这题点数20w操作10w,LCT卡常估计过不去.看到这个东西只有两行,考虑能否用魔改后的线性数据结构去维护.我想到了线段树. 考虑如果两 ...

  8. bzoj1018[SHOI2008]堵塞的交通traffic——线段树

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=1018 巧妙的线段树.维护矩阵四个角的连通性. 考虑两个点连通的可能路径分成3部分:两点左边. ...

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

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

随机推荐

  1. SequoiaDB培训视频

    很久之前录制的SequoiaDB培训视频,现在都放上百度云盘了,感兴趣的同学可以看看. 第一讲:图形界面-安装前准备 链接: https://pan.baidu.com/s/1d2B3qUYqtKrE ...

  2. 如何使用sass

    Sass 是对 CSS 的扩展,让 CSS 语言更强大.优雅. 它允许你使用变量.嵌套规则.mixin.导入等众多功能, 并且完全兼容 CSS 语法. Sass 有助于保持大型样式表结构良好, 同时也 ...

  3. 微信小程序 笔记

    1.Input 输入控件 <input type='digit' placeholder='0.00'></input> 如果要使用单纯的数字控件,使那么可以将type设置为d ...

  4. windows无法启动redis服务,错误码1067

    https://blog.csdn.net/kissdead0xzy/article/details/84332870

  5. nginx的配置文件server_name的意义 location意义

    配置不同的域名      不同域名都可以有首地址 location   同一域名下   分发到不同的路径   或者项目

  6. Hybrid app(cordova) 环境配置记录

    node版本管理 NVM 安装过程 由于最新版 node 不兼容部分功能,所以需要安装 nvm 切换 node 版本 在 https://github.com/coreybutler/nvm-wind ...

  7. 基于WebSocket和SpringBoot的群聊天室

    引入 普通请求-响应方式:例如Servlet中HttpServletRequest和HttpServletResponse相互配合先接受请求.解析数据,再发出响应,处理完成后连接便断开了,没有数据的实 ...

  8. Java基础(变量、运算符)

    第2天 Java基础语法 今日内容介绍 u 变量 u 运算符 第1章 变量 1.1 变量概述 前面我们已经学习了常量,接下来我们要学习变量.在Java中变量的应用比常量的应用要多很多.所以变量也是尤为 ...

  9. js插件设置innerHTML时,在IE8下报错“未知运行时错误”

    问题描述: 网站中使用了一个js插件,设置innerHTML时,在IE8下报错“未知运行时错误”: <div id=”divContainer”> <a name=”link”> ...

  10. C++拾遗(五)——类

    类是 C++ 中最重要的特征.C++ 语言的早期版本被命名为“带类的 C(Cwith Classes)”,以强调类机制的中心作用.随着语言的演变,创建类的配套支持也在不断增加.语言设计的主要目标也变成 ...