• [SHOI2008]堵塞的交通traffic


    线段树维护连通性。。。

    通过分析我们可以发现,一个城市到另一个城市一共只有很少的几种情况

    所以我们可以维护这个 2*X 矩形

    判断其 从左上角到左下角

         左上角到右上角

         左上角到右下角

         左下角到右上角

         左下角到右下角

         右上角到右下角

                的连通性

    通过得到的连通性再判断即可

    呆码:

    #include<iostream>
    #include<cstdio>
    using namespace std;
    
    struct asd{
        bool luru,ldrd;
        bool lurd,ldru;
        bool luld,rurd;
        bool self[3];
    } a[100010*4];
    // l:left ; r:right ; u:up ; d:down
    // 表示能否从一个角到另一个角 
    
    int r1,r2,c1,c2,n;
    
    inline asd pushup(asd x,asd y)
    {
        asd ans;
        ans.luru=ans.ldrd=0;
        ans.lurd=ans.ldru=0;
        ans.luld=ans.rurd=0;
        ans.self[1]=y.self[1],ans.self[2]=y.self[2];
        if((x.luru && x.self[1] && y.luru) || (x.lurd && x.self[2] && y.ldru)) ans.luru=1;
        if((x.ldrd && x.self[2] && y.ldrd) || (x.ldru && x.self[1] && y.lurd)) ans.ldrd=1;
        if((x.luru && x.self[1] && y.lurd) || (x.lurd && x.self[2] && y.ldrd)) ans.lurd=1;
        if((x.ldrd && x.self[2] && y.ldru) || (x.ldru && x.self[1] && y.luru)) ans.ldru=1;
        if((x.luld) || (x.luru && x.self[1] && y.luld && x.self[2] && x.ldrd)) ans.luld=1;
        if((y.rurd) || (y.luru && x.self[1] && x.rurd && x.self[2] && y.ldrd)) ans.rurd=1;
        return ans;
    }
    
    inline void build(int rt,int l,int r)
    {
        if(l==r)
        {
            a[rt].luru=a[rt].ldrd=1;
            return;
        }
        int mid=l+r>>1;
        build(rt<<1,l,mid);
        build(rt<<1|1,mid+1,r);
        a[rt]=pushup(a[rt<<1],a[rt<<1|1]);
    }
    
    inline void change1(int rt,int l,int r,int L,int k)
    {
        if(l==r)
        {
            a[rt].lurd=a[rt].ldru=a[rt].luld=a[rt].rurd=k;
            return;
        }
        int mid=l+r>>1;
        if(L<=mid) change1(rt<<1,l,mid,L,k);
        else change1(rt<<1|1,mid+1,r,L,k);
        a[rt]=pushup(a[rt<<1],a[rt<<1|1]);
    }
    
    inline void change2(int rt,int l,int r,int L,int y,int k)
    {
        if(l==r)
        {
            a[rt].self[y]=k;
            return;
        }
        int mid=l+r>>1;
        if(L<=mid) change2(rt<<1,l,mid,L,y,k);
        else change2(rt<<1|1,mid+1,r,L,y,k);
        a[rt]=pushup(a[rt<<1],a[rt<<1|1]);
    }
    
    inline asd query(int rt,int l,int r,int L,int R)
    {
        if(L<=l && r<=R) { return a[rt]; }
        int mid=l+r>>1;
        asd ans1,ans2;
        bool left=0,right=0;
        if(L<=mid) ans1=query(rt<<1,l,mid,L,R),left=1;
        if(R>mid) ans2=query(rt<<1|1,mid+1,r,L,R),right=1;
        if(left==1 && right==1) return pushup(ans1,ans2);
        else return left==1 ? ans1 : ans2;
    }
    
    inline bool check()
    {
        if(c1>c2) { swap(c1,c2); swap(r1,r2); }
        asd pre=query(1,1,n,1,c1);
        asd now=query(1,1,n,c1,c2);
        asd nxt=query(1,1,n,c2,n);
        if(r1==r2)
        {
            if(r1==1 && ((now.luru) || (pre.rurd && now.ldru) || (nxt.luld && now.lurd) || (pre.rurd && now.ldrd && nxt.luld))) return 1;
            if(r1==2 && ((now.ldrd) || (pre.rurd && now.lurd) || (nxt.luld && now.ldru) || (pre.rurd && now.luru && nxt.luld))) return 1;
        }
        else
        {
            if(r1==1 && ((now.lurd) || (pre.rurd && now.ldrd) || (nxt.luld && now.luru) || (pre.rurd && now.ldru && nxt.luld))) return 1;
            if(r1==2 && ((now.ldru) || (pre.rurd && now.luru) || (nxt.luld && now.ldrd) || (pre.rurd && now.lurd && nxt.luld))) return 1;
        }
        return 0;
    }
    
    int main()
    {
        scanf("%d",&n);
        build(1,1,n);
        while(1)
        {
            char ch[10]; scanf("%s",ch);
            if(ch[0]=='E') break;
            scanf("%d%d%d%d",&r1,&c1,&r2,&c2);
            if(ch[0]=='O')
            {
                if(c1==c2) change1(1,1,n,c1,1);
                else change2(1,1,n,min(c1,c2),r1,1);
            }
            if(ch[0]=='C')
            {
                if(c1==c2) change1(1,1,n,c1,0);
                else change2(1,1,n,min(c1,c2),r1,0);
            }
            if(ch[0]=='A')
            {
                if(check()) printf("Y
    ");
                else printf("N
    ");
            }
        }
        return 0;
    }
    代码
  • 相关阅读:
    关于GET和POST请求的区别,最通俗全面的回答
    Mac常用命令行
    Jquery中的done() fail() then() $when()到底是什么
    聊聊HTML5中的Web Notification桌面通知
    css实现左右两个div等高
    css样式优先级计算规则
    vue获取后端数据放在created还是mounted方法里面?
    vue的provide和inject特性
    前端路由的实现原理
    Windows鼠标右键新建中增加新建md文件
  • 原文地址:https://www.cnblogs.com/zzzyc/p/9536282.html
Copyright © 2020-2023  润新知