传送门ber~

哇这个线段树好神啊!!

用线段树维护图连通性,每个节点开个二维数组 ai,j a i , j a_{i,j}表示这个区间最左面的第 i i i行能不能走到最右面的第j" role="presentation" style="position: relative;">jjj行,同时记录一下最左最右第一行与第二行是否都能互相走到
这六个东西可以用线段树维护啊(看代码)!

细节有点多…具体看代码吧…
注释说的很清楚(自信)

代码如下:

#include<algorithm>
#include<cstring>
#include<ctype.h>
#include<cstdio>
#define N 100050
using namespace std;
inline int read(){int x=0,f=1;char c;do c=getchar(),f=c=='-'?-1:f; while(!isdigit(c));do x=(x<<3)+(x<<1)+c-'0',c=getchar(); while(isdigit(c));return x*f;
}
bool b1[N],b2[N][3];///b1是纵向的边 b2是横向的边(向右指的)
struct Status{bool b[2][2],lb,rb;int l,r;inline void init(int x,int y){l=x;r=y;memset(b,false,sizeof b);lb=rb=false;return;}Status operator + (const Status k) const{Status tmp;tmp.l=l;tmp.r=k.r;tmp.lb=lb|(b2[r][1]&b2[r][2]&b[0][0]&b[1][1]&k.lb);///合并当前状态和k状态,每个情况yy一下就非常好理解了tmp.rb=k.rb|(b2[r][1]&b2[r][2]&k.b[0][0]&k.b[1][1]&rb);tmp.b[0][0]=(b[0][0]&k.b[0][0]&b2[r][1])|(b[0][1]&k.b[1][0]&b2[r][2]);tmp.b[0][1]=(b[0][0]&k.b[0][1]&b2[r][1])|(b[0][1]&k.b[1][1]&b2[r][2]);tmp.b[1][0]=(b[1][0]&k.b[0][0]&b2[r][1])|(b[1][1]&k.b[1][0]&b2[r][2]);tmp.b[1][1]=(b[1][0]&k.b[0][1]&b2[r][1])|(b[1][1]&k.b[1][1]&b2[r][2]);return tmp;}
};
struct Node{Node *ls,*rs;Status a;///存的状态int l,r;inline void maintain(){if(l==r) return;a=ls->a+rs->a;return;}
}*root=new Node;
void maketree(int l,int r,Node *x){x->l=l;x->r=r;x->a.init(l,r);if(l==r){x->a.b[0][0]=x->a.b[1][1]=true;///建树,一定要将单个点的这个赋成truereturn;}int mid=(l+r)>>1;maketree(l,mid,x->ls=new Node);maketree(mid+1,r,x->rs=new Node);x->maintain();return;
}
void Modify_Up(int x,bool v,Node *k){///修改竖着的边,就是将线段树的单个节点的连通性修改一下if(k->l==k->r){k->a.b[0][1]=k->a.b[1][0]=v;k->a.lb=k->a.rb=v;return;}int mid=(k->l+k->r)>>1;if(x<=mid) Modify_Up(x,v,k->ls);else Modify_Up(x,v,k->rs);k->maintain();return;
}
void Update(int x,Node *k){///因为更改一条x到y的横着的边只会影响最多两串,只要到底部然后回溯时维护就好了if(k->l==k->r) return;int mid=(k->l+k->r)>>1;if(x<=mid) Update(x,k->ls);else Update(x,k->rs);k->maintain();return;
}
Status Query(int x,int y,Node *k){///询问,就是将所有子段的信息合并if(k->l>=x && k->r<=y){return k->a;}int mid=(k->l+k->r)>>1;if(y<=mid) return Query(x,y,k->ls);else if(x>mid) return Query(x,y,k->rs);else return Query(x,y,k->ls)+Query(x,y,k->rs);
}
int n,x,y,x1,y1;
char c[5];
bool ans;
int main(){n=read();maketree(1,n,root);while(""){scanf("%s",c+1);if(c[1]=='O'){x=read();y=read();x1=read();y1=read();if(y==y1){b1[y]=true;Modify_Up(y,true,root);///修改纵向的边,在线段树上修改}else{if(y>y1) swap(y,y1),swap(x,x1);///同下b2[y][x]=true;Update(y,root);Update(y1,root);}}else if(c[1]=='C'){x=read();y=read();x1=read();y1=read();if(y==y1){///同上b1[y]=false;Modify_Up(y,false,root);}else{if(y>y1) swap(y,y1),swap(x,x1);b2[y][x]=false;///修改横向的边,只要重新维护一遍就可以了Update(y,root);Update(y1,root);}}else if(c[1]=='A'){x=read();y=read();x1=read();y1=read();if(y>y1) swap(x,x1),swap(y,y1);Status l=Query(1,y,root),k=Query(y,y1,root),r=Query(y1,n,root);///注意这里,l是左面的区域,目的是统计从左面绕过去的方案,r同理if(x==1 && x1==1) ans=k.b[0][0] | (l.rb & k.b[1][0]) | (r.lb & k.b[0][1]) | (r.lb & l.rb & k.b[1][1]);///每个情况判断一下..还是挺恶心的if(x==1 && x1==2) ans=k.b[0][1] | (l.rb & k.b[1][1]) | (r.lb & k.b[0][0]) | (r.lb & l.rb & k.b[1][0]);if(x==2 && x1==1) ans=k.b[1][0] | (l.rb & k.b[0][0]) | (r.lb & k.b[1][1]) | (r.lb & l.rb & k.b[0][1]);if(x==2 && x1==2) ans=k.b[1][1] | (l.rb & k.b[0][1]) | (r.lb & k.b[1][0]) | (r.lb & l.rb & k.b[0][0]);puts(ans?"Y":"N");}else if(c[1]=='E') return 0;}
return 0;
}

BZOJ[1018][SHOI2008]堵塞的交通traffic 线段树相关推荐

  1. BZOJ 1018: [SHOI2008]堵塞的交通traffic(线段树分治+并查集)

    传送门 解题思路 可以离线,然后确定每个边的出现时间,算这个排序即可.然后就可以线段树分治了,连通性用并查集维护,因为要撤销,所以要按秩合并,时间复杂度\(O(nlog^2 n)\) 代码 #incl ...

  2. BZOJ 1018: [SHOI2008]堵塞的交通traffic

    二次联通门 : BZOJ 1018: [SHOI2008]堵塞的交通traffic /*BZOJ 1018: [SHOI2008]堵塞的交通traffic麻麻这题玩我这题简直消磨人的意志写了一天了写一 ...

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

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

  4. 【BZOJ】1018: [SHOI2008]堵塞的交通traffic

    http://www.lydsy.com/JudgeOnline/problem.php?id=1018 题意:有2行,每行有c(c<=100000)个城市,则一共有c-1个格子,现在有q(q& ...

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

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

  6. Bzoj1018 [SHOI2008]堵塞的交通traffic

    Time Limit: 3 Sec  Memory Limit: 162 MB Submit: 3458  Solved: 1158 Description 有一天,由于某种穿越现象作用,你来到了传说 ...

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

    题目链接:bzoj1018 题目大意: 一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个城市和3C-2条道路. 交通信息可以分为以下几种格式: Close ...

  8. [SHOI2008]堵塞的交通traffic

    线段树维护连通性... 通过分析我们可以发现,一个城市到另一个城市一共只有很少的几种情况 所以我们可以维护这个 2*X 矩形 判断其 从左上角到左下角 左上角到右上角 左上角到右下角 左下角到右上角 ...

  9. BZOJ1018: [SHOI2008]堵塞的交通traffic

    线段树维护每一块左上到左下.右上到右下.左上到右上.左下到右下.左上到右下.左下到右上的联通情况. upd:可以直接用3082的方法搞,能过. #include<bits/stdc++.h> ...

最新文章

  1. qcustomplot删除一条曲线_微凉秋日的成熟风穿搭,选一条V领连衣裙搭配,优雅知性显身材...
  2. BAT3四大巨头安全负责人破天荒聚在了一起,他们都说了什么?
  3. jquery --- 网页选项卡
  4. 使用data()方法缓存数据
  5. 计算机视觉基本原理介绍—RANSAC
  6. Linux软件安装为什么名字不一样
  7. navicat premium相关应用(将oracle数据库迁移到mysql等)
  8. 界面无小事(六):来做个好看得侧拉菜单!
  9. Mac好用的图片压缩软件——JPG Compress 2 for Mac
  10. web前端优化一些看法
  11. cad线性标注命令_CAD线性标注命令的使用方法
  12. 怎样把自己喜欢的微信表情包(动态)导出来,我三岁半的表弟都会...
  13. clickhouse ARRAY JOIN函数
  14. 在vue中使用wow动画插件(下载,配置,使用,参数)
  15. 2020Pyton开发者日线上技术峰会主题:爬虫框架的技术实现与模块应用的经验分享
  16. 营销组合(4P营销)分析案例:采用SPSS+Excel进行分析
  17. HDU 5238 Calculator【线段树】
  18. js正则表达式(2)
  19. python 输入学生成绩大于 90为优_c++ 输入学生成绩,打印出该学生成绩等级,大于等于90为A,小于90且大于等于80为B,小...
  20. 【礼堂椅安装】礼堂椅影院椅组装步骤方法

热门文章

  1. 大学四年计算机旅途,那些惊艳我们的高效算法
  2. Codeforces//Good Bye 2013//A. New Year Candles 水题
  3. 访问 localhost 的请求遭到拒绝_软件架构-Spring Cloud Zuul作为API网关实现请求路由转发...
  4. 【C++---10】有参宏,无参宏,宏的优缺点
  5. 【H.264/AVC视频编解码技术详解】二十六、帧间预测编码(4):宏块的帧间预测解码
  6. Postman Chrome插件
  7. 报告称逾千万网游玩家涉及非官方渠道虚拟交易
  8. 四大会计师事务所python数据分析_四大VS八大|会计师事务所实习
  9. css loading 字体动画效果,CSS实现四种loading动画效果
  10. vs2015mfc编程c语言,计算机技术《VS2015_MFC编程入门》.pdf