线段树的每个叶子节点存一列。

每个节点维护六个域,分别是左上左下、左上右上、左上右下、左下右上、左下右下、右上右下在区间内部的连通性,不考虑绕出去的情况。

初始每个叶子的左上左下、右上右下是连通的。

每次修改纵列时,直接去线段树里修改。

每次修改横行时,将其左右两列全都pushup一遍。

具体怎么维护,并不难,请自行思考。

每次询问时,提取出来[1,l-1],[l,r],[r+1,n]的连通性,然后讨论是否绕出来的情况。

不推荐使用循环维护,人工讨论反而更加方便。

  1. #include<cstdio>
  2. #include<algorithm>
  3. using namespace std;
  4. #define N 100001
  5. int n;
  6. bool heng[2][N];/*heng(i,j)±íʾ(i,j)ºÍ(i+1,j)Ö®¼äÊÇ·ñÓбß*/
  7. bool zong[N];/*zong(i)±íʾ(0,i)ºÍ(1,i)Ö®¼äÊÇ·ñÓбß*/
  8. struct Node{bool zszx,zsys,zsyx,zxys,zxyx,ysyx;}T[N<<2];
  9. /*!!!ÐèÒªµ¥¶ÀÌÖÂÛµ¥¸ö×ÝÁкÍÆäËûµÄºÏ²¢µÄÇé¿ö!!!...ºÃ°ÉÆäʵ²»ÓÃ...³õʼʱÿ¸ö×ÝÁеÄzsys,zxyx=1*/
  10. inline void pushup(Node &rt,const Node &ls,const Node &rs,const int &r1)
  11. {
  12. if(ls.zszx) rt.zszx=1;//zszx
  13. else if(ls.zsys && rs.zszx && ls.zxyx && heng[0][r1] && heng[1][r1]) rt.zszx=1;
  14. else rt.zszx=0;
  15. if(rs.ysyx) rt.ysyx=1;//ysyx
  16. else if(rs.zsys && ls.ysyx && rs.zxyx && heng[0][r1] && heng[1][r1]) rt.ysyx=1;
  17. else rt.ysyx=0;
  18. if(ls.zsys && rs.zsys && heng[0][r1]) rt.zsys=1;//zsys
  19. else if(ls.zsyx && rs.zxys && heng[1][r1]) rt.zsys=1;
  20. else rt.zsys=0;
  21. if(ls.zsys && rs.zsyx && heng[0][r1]) rt.zsyx=1;//zsyx
  22. else if(ls.zsyx && rs.zxyx && heng[1][r1]) rt.zsyx=1;
  23. else rt.zsyx=0;
  24. if(ls.zxys && rs.zsys && heng[0][r1]) rt.zxys=1;//zxys
  25. else if(ls.zxyx && rs.zxys && heng[1][r1]) rt.zxys=1;
  26. else rt.zxys=0;
  27. if(ls.zxys && rs.zsyx && heng[0][r1]) rt.zxyx=1;//zxyx
  28. else if(ls.zxyx && rs.zxyx && heng[1][r1]) rt.zxyx=1;
  29. else rt.zxyx=0;
  30. }
  31. void update(int p,bool v,int rt,int l,int r)/*µ¥×ÝÁÐÐÞ¸Ä*/
  32. {
  33. if(l==r)
  34. {
  35. zong[p]=v;
  36. T[rt].zszx=T[rt].zsyx=T[rt].zxys=T[rt].ysyx=v;
  37. return;
  38. }
  39. int m=(l+r>>1);
  40. if(p<=m) update(p,v,rt<<1,l,m);
  41. else update(p,v,rt<<1|1,m+1,r);
  42. pushup(T[rt],T[rt<<1],T[rt<<1|1],m);
  43. }
  44. void update(int p,int rt,int l,int r)/*ÓÉÓÚÅԱߵĺáÐнøÐÐÁËÐ޸Ķø½øÐеĵ¥×ÝÁиüÐÂ*/
  45. {
  46. if(l==r) return;
  47. int m=(l+r>>1);
  48. if(p<=m) update(p,rt<<1,l,m);
  49. else update(p,rt<<1|1,m+1,r);
  50. pushup(T[rt],T[rt<<1],T[rt<<1|1],m);
  51. }
  52. Node query(int ql,int qr,int rt,int l,int r)
  53. {
  54. if(ql<=l && r<=qr) return T[rt];
  55. int m=(l+r>>1);
  56. if(ql<=m && m<qr)
  57. {
  58. Node res;
  59. pushup(res,query(ql,qr,rt<<1,l,m),query(ql,qr,rt<<1|1,m+1,r),m);
  60. return res;
  61. }
  62. else if(ql<=m) return query(ql,qr,rt<<1,l,m);
  63. else return query(ql,qr,rt<<1|1,m+1,r);
  64. }
  65. inline bool query(const bool &x1,const int &y1,const bool &x2,const int &y2)
  66. {
  67. Node M=query(y1,y2,1,1,n),L,R;
  68. if(y1!=1) L=query(1,y1-1,1,1,n);
  69. if(y2!=n) R=query(y2+1,n,1,1,n);
  70. if(x1 && x2)
  71. {
  72. if(M.zxyx) return 1;
  73. if(y1!=1) if(L.ysyx && M.zsyx && heng[0][y1-1] && heng[1][y1-1]) return 1;
  74. if(y2!=n) if(R.zszx && M.zxys && heng[0][y2] && heng[1][y2]) return 1;
  75. if(y1!=1 && y2!=n) if(L.ysyx && heng[0][y1-1] && heng[1][y1-1]
  76. && R.zszx && heng[0][y2] && heng[1][y2] && M.zsys)
  77. return 1;
  78. return 0;
  79. }
  80. else if(x1)
  81. {
  82. if(M.zxys) return 1;
  83. if(y1!=1) if(L.ysyx && M.zsys && heng[0][y1-1] && heng[1][y1-1]) return 1;
  84. if(y2!=n) if(R.zszx && M.zxyx && heng[0][y2] && heng[1][y2]) return 1;
  85. if(y1!=1 && y2!=n) if(L.ysyx && heng[0][y1-1] && heng[1][y1-1]
  86. && R.zszx && heng[0][y2] && heng[1][y2] && M.zsyx)
  87. return 1;
  88. return 0;
  89. }
  90. else if(x2)
  91. {
  92. if(M.zsyx) return 1;
  93. if(y1!=1) if(L.ysyx && M.zxyx && heng[0][y1-1] && heng[1][y1-1]) return 1;
  94. if(y2!=n) if(R.zszx && M.zsys && heng[0][y2] && heng[1][y2]) return 1;
  95. if(y1!=1 && y2!=n) if(L.ysyx && heng[0][y1-1] && heng[1][y1-1]
  96. && R.zszx && heng[0][y2] && heng[1][y2] && M.zxys)
  97. return 1;
  98. return 0;
  99. }
  100. else
  101. {
  102. if(M.zsys) return 1;
  103. if(y1!=1) if(L.ysyx && M.zxys && heng[0][y1-1] && heng[1][y1-1]) return 1;
  104. if(y2!=n) if(R.zszx && M.zsyx && heng[0][y2] && heng[1][y2]) return 1;
  105. if(y1!=1 && y2!=n) if(L.ysyx && heng[0][y1-1] && heng[1][y1-1]
  106. && R.zszx && heng[0][y2] && heng[1][y2] && M.zxyx)
  107. return 1;
  108. return 0;
  109. }
  110. }
  111. int main()
  112. {
  113. // freopen("bzoj1018.in","r",stdin);
  114. char op[7];
  115. int x1,x2,y1,y2;
  116. scanf("%d",&n);
  117. for(int i=1;i<=(n<<2);++i)
  118. T[i].zsys=T[i].zxyx=1;
  119. while(1)
  120. {
  121. scanf("%s",op);
  122. if(op[0]=='E') break;
  123. else if(op[0]=='O')
  124. {
  125. scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
  126. if(y1==y2) update(y1,1,1,1,n);
  127. else
  128. {
  129. if(y1>y2) swap(y1,y2);
  130. heng[x1-1][y1]=1;
  131. update(y1,1,1,n);
  132. update(y2,1,1,n);
  133. }
  134. }
  135. else if(op[0]=='C')
  136. {
  137. scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
  138. if(y1==y2) update(y1,0,1,1,n);
  139. else
  140. {
  141. if(y1>y2) swap(y1,y2);
  142. heng[x1-1][y1]=0;
  143. update(y1,1,1,n);
  144. update(y2,1,1,n);
  145. }
  146. }
  147. else
  148. {
  149. scanf("%d%d%d%d",&x1,&y1,&x2,&y2);
  150. if(y1>y2)
  151. {
  152. swap(x1,x2);
  153. swap(y1,y2);
  154. }
  155. puts(query(x1-1,y1,x2-1,y2) ? "Y" : "N");
  156. }
  157. }
  158. return 0;
  159. }

【线段树】bzoj1018 [SHOI2008]堵塞的交通traffic的更多相关文章

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

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

  2. bzoj千题计划108:bzoj1018: [SHOI2008]堵塞的交通traffic

    http://www.lydsy.com/JudgeOnline/problem.php?id=1018 关键点在于只有两行 所以一个2*m矩形连通情况只有6种 编号即对应代码中的a数组 线段树维护 ...

  3. 【离线 撤销并查集 线段树分治】bzoj1018: [SHOI2008]堵塞的交通traffic

    本题可化成更一般的问题:离线动态图询问连通性 当然可以利用它的特殊性质,采用在线线段树维护一些标记的方法 Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常 ...

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

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

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

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

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

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

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

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

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

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

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

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

随机推荐

  1. 发邮件 和 excel导出中文文件名

    /** * 发邮件 * @param email * @param subject * @param body * @throws UnsupportedEncodingException */ pu ...

  2. spark 特殊函数

    private var seed: Long = System.nanoTime()//返回最准确的可用系统计时器的当前值,以毫微秒为单位 require(storageLevel != Storag ...

  3. 各种Java序列化性能比较

    转载:http://www.jdon.com/concurrent/serialization.html 这里比较Java对象序列化 XML JSON  Kryo  POF等序列化性能比较. 很多人以 ...

  4. Angularjs学习笔记(一)

    大部分传统的模板系统,对模板的渲染是个线性单向的过程:模板或变量与模板混合在一起产生结果的标记集合.任何对模型的改变都需要通过模板的重新计算.但AngularJS有所不同,任何用户引发的视图的改变,都 ...

  5. IOS (APP 启动 相应处理)

    APP 每次启动的入口都是通过: - (BOOL)application:(UIApplication *)application didFinishLaunchingWithOptions:(NSD ...

  6. [知识整理]Java集合

    Mark Java集合图

  7. Android开源框架——Volley

    Volley 是 Google 在 2013 I/O 大会上推出的 Android 异步网络请求框架和图片加载框架.特别适合数据量小,通信频繁的网络操作.Volley 主要是通过两种 Diapatch ...

  8. Masonry控制台打印约束冲突问题解决

    不知道你是不是视图的布局也是用的第三方Masonry,在使用中是不是也遇到了控制台约束冲突的警告打印,看下图: 从输出的信息可以知道,有的控件的约束明显重复了设置,所以指出了是哪个控件,重复设置了哪些 ...

  9. android之handle

    Android中异步消息处理主要由四个部分组成,Message.handler.messageQueue和looper. 1.message message是线程之间传递的消息,他可以在内部携带少量的 ...

  10. xtrareport实现指定记录数以及填补空白行(网上整理)

    在Detail的事件中: int i=0; private void OnBeforePrint(object sender, System.Drawing.Printing.PrintEventAr ...