bzoj 1018 堵塞的交通traffic (线段树)

题意:

思路:

参考博客:https://www.cnblogs.com/MashiroSky/p/5973686.html
        非常非常难写的线段树,不仅难想还难写。
        首先,这个线段树维护的是什么,是该区域四个顶点的连通性
这里写图片描述
       比如维护一个宽度为6的区域,我们维护的就是图中1,2,3,4的连通性。
       然后考虑怎么合并两个区间,因为合并的时候,两个子区间都是已经内部联通好的了,因为我们并不在意具体路径,只要能联通就可以了,所以,合并区间就相当于这样:
这里写图片描述
       其中1234为左儿子的区间,5678为右儿子的区间,我们发现想要合并两个区间,就需要知道25,47的连通性,也就是mid和mid+1的连通性。
       事实上,最后我们维护了8个连通性,分别是1和2,1和3,1和4,2和3,3和4,2和4,mid和mid+1的第一行连通性,mid和mid+1的第二行连通性。
       具体更新的时候,两个格子的相对位置是需要分类讨论的。而pushup的操作大家在理解连通性以后就很好理解了。
       最后想想怎么查询,比如我们询问上图2,7的连通性,其中2可能需要先向左跑,然后再跑到7(上面贴的dalao的博客有更详细的解释),正是因为这种情况,我们就需要把区间切成3部分(就是三个区间),第一部分是1到c1,第二部分是c1到c2,第三部分是c2到n。这样就能处理掉上面说的跑法了。

错误及反思:

代码:

代码也参考了大佬的代码(其实最后都改得没啥区别了),说句实话,没这位dalao的代码我根本写不出来,太难写了

#include<bits/stdc++.h>
using namespace std;
const int N = 201000;
#define ls rt<<1
#define rs rt<<1|1

 /*
 U:第一行mid,mid+1两列之间是否联通
 D:第二行mid,mid+1两列之间是否联通
 l:s1,s3是否联通
 r:s2,s4是否联通
 u:s1,s2是否联通
 d:s3,s4是否联通
 q:s1,s4是否联通
 p:s3,s2是否联通
 */

int n;
char s[10];
struct Segtree{
    int U,D,l,r,u,d,q,p;
}seg[N<<2];

void pushup(Segtree &rt,Segtree l,Segtree r){
    rt.l=l.l||(l
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值