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

传送门biu~

#include<bits/stdc++.h>
#define N 100005
using namespace std;
bool edge[N][2];
struct state{
    bool b[2][2],lb,rb;
    int l,r;
    state(int _=0,int __=0){
        l=_;r=__;
        memset(b,false,sizeof b);
        lb=rb=false;
    }
    state operator+(const state&k)const{
        state re=state(l,k.r);
        re.lb=lb|(edge[r][0]&edge[r][1]&b[0][0]&b[1][1]&k.lb);
        re.rb=k.rb|(edge[r][0]&edge[r][1]&k.b[0][0]&k.b[1][1]&rb);
        for(int i=0;i<=1;++i)
            for(int j=0;j<=1;++j)
                for(int h=0;h<=1;++h)
                    re.b[i][j]|=b[i][h]&edge[r][h]&k.b[h][j];
        return re;
    }
};
struct Node{
    Node *ch[2];
    int l,r;
    state a;
    inline void maintain(){
        if(l==r)    return;
        a=ch[0]->a+ch[1]->a;
    }
}*root;
void buildtree(Node *&o,int l,int r){
    o=new Node;
    o->l=l;o->r=r;
    o->a=state(l,r);
    if(l==r){
        o->a.b[0][0]=o->a.b[1][1]=true;
        return;
    }
    int mid=l+r>>1;
    buildtree(o->ch[0],l,mid);
    buildtree(o->ch[1],mid+1,r);
    o->maintain();
}
void Modify(Node *&o,int x,int v){
    if(o->l==o->r){o->a.b[0][1]=o->a.b[1][0]=o->a.lb=o->a.rb=v;return;}
    int mid=o->l+o->r>>1;
    if(x<=mid)  Modify(o->ch[0],x,v);
    else        Modify(o->ch[1],x,v);
    o->maintain();
}
void Update(Node *o,int x){
    if(o->l==o->r)  return;
    int mid=o->l+o->r>>1;
    if(x<=mid)  Update(o->ch[0],x);
    else        Update(o->ch[1],x);
    o->maintain();
}
state Query(Node *o,int l,int r){
    if(o->l==l && o->r==r)  return o->a;
    int mid=o->l+o->r>>1;
    if(r<=mid)      return Query(o->ch[0],l,r);
    else if(l>mid)  return Query(o->ch[1],l,r);
    else return Query(o->ch[0],l,mid)+Query(o->ch[1],mid+1,r);
}
int main(){
    int n;
    scanf("%d",&n);
    buildtree(root,1,n);
    while(1){
        char opt[10];
        scanf("%s",opt);
        if(opt[0]=='O'){
            int x1,yl,x2,y2;
            scanf("%d%d%d%d",&x1,&yl,&x2,&y2);--x1;--x2;
            if(yl==y2)  Modify(root,yl,true);
            else{
                if(yl>y2)   swap(x1,x2),swap(yl,y2);
                edge[yl][x1]=true;
                Update(root,yl);Update(root,y2);
            }
        }
        else if(opt[0]=='C'){
            int x1,yl,x2,y2;
            scanf("%d%d%d%d",&x1,&yl,&x2,&y2);--x1;--x2;
            if(yl==y2)  Modify(root,yl,false);
            else{
                if(yl>y2)   swap(x1,x2),swap(yl,y2);
                edge[yl][x1]=false;
                Update(root,yl);Update(root,y2);
            }
        }
        else if(opt[0]=='A'){
            int x1,yl,x2,y2;
            scanf("%d%d%d%d",&x1,&yl,&x2,&y2);--x1;--x2;
            if(yl>y2)   swap(x1,x2),swap(yl,y2);
            state l=Query(root,1,yl),k=Query(root,yl,y2),r=Query(root,y2,n);
            int ans=k.b[x1][x2]|(l.rb&k.b[x1^1][x2])|(r.lb&k.b[x1][x2^1])|(l.rb&r.lb&k.b[x1^1][x2^1]);
            puts(ans?"Y":"N");
        }
        else break;
    }
    return 0;
}
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 打赏
    打赏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

zP1nG

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值