zoukankan      html  css  js  c++  java
  • bzoj1018: [SHOI2008]堵塞的交通traffic

    线段树维护联通性。

    题目下方有分析。

    题解里面说的行数等于题目中的行数-1.

    经过分析一共(r1,c1)->(r2,c2)一共有四种方式。

    假设r1=1,r2=0。

    1.直接过去。

    2.先到(0,c1)再过去。

    3.先到(1,c2)再过去。

    4.先到(0,c1)再到(1,c2)再过去。

    用一个数组a1[i][j],维护从x节点最左端的i行能否到最右端的j行。

    另一个数组a2[i],a2[0]表示x节点最右端的点能不能从右面绕到另外一行。a2[1]代表最左端的点能不能从左面绕到另外一行。

    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    using namespace std;
    const int maxn = 800000 + 10;
    
    char s[20];
    int x1,x2,y1,y2,c;
    
    struct Segtree {
        #define lc(x) ((x)<<1)
        #define rc(x) (((x)<<1)|1)
        #define root 1
        
        struct Status {
            int a1[2][2],a2[2];    
        }s[maxn];
        
        bool b[maxn][2];
        int l[maxn],r[maxn],m[maxn];
        
        Status update(Status s1,Status s2,bool b[]) {
            Status res;
            for(int i=0;i<=1;i++) 
            for(int j=0;j<=1;j++) 
                res.a1[i][j]=s1.a1[i][0] && b[0] && s2.a1[0][j] || s1.a1[i][1] && b[1] && s2.a1[1][j];         
            res.a2[0]=s1.a2[0] || s1.a1[0][0] && b[0] && s2.a2[0] && b[1] && s1.a1[1][1];
            res.a2[1]=s2.a2[1] || s2.a1[0][0] && b[0] && s1.a2[1] && b[1] && s2.a1[1][1];
            return res;
        }
        
        Status access (int x,int y1,int y2) {
            if(y1<=l[x] && r[x]<=y2) return s[x];
            else if(y2<=m[x]) return access(lc(x),y1,y2);
            else if(y1>m[x]) return access(rc(x),y1,y2);
            else return update(access(lc(x),y1,y2),access(rc(x),y1,y2),b[x]);
        }
        
        void change(bool k,int x,int x1,int y1,int x2,int y2) {
            if(x1==x2 && y1==m[x]) {
                b[x][x1]=k;
                s[x]=update(s[lc(x)],s[rc(x)],b[x]);
            }
            else if(l[x]==r[x]) 
                s[x].a1[0][1]=s[x].a1[1][0]=s[x].a2[0]=s[x].a2[1]=k;
            else {
                change(k,y2<=m[x]?lc(x):rc(x),x1,y1,x2,y2);
                s[x]=update(s[lc(x)],s[rc(x)],b[x]);    
            }
        }
        
        void ask(int x1,int y1,int x2,int y2) {
            Status left=access(root,1,y1),
                   right=access(root,y2,c),
                   mid=access(root,y1,y2);
            bool res=false;
            for(int i=0;i<=1;i++)
            for(int j=0;j<=1;j++)
                if(mid.a1[i][j]&&(i==x1||left.a2[1])&&(j==x2||right.a2[0])) {
                    res=true; break;
                }
            printf(res?"Y
    ":"N
    ");
        }
        
        void build(int x,int y1,int y2) {
            l[x]=y1,r[x]=y2,m[x]=(l[x]+r[x])>>1;    
            if(y1==y2) 
                s[x].a1[0][0]=s[x].a1[1][1]=true;
            else {
                build(lc(x),y1,m[x]);
                build(rc(x),m[x]+1,y2);    
            }
        }
    }seg;
    
    int main() {
        scanf("%d",&c);
        seg.build(1,1,c);
        while(1) {
            scanf("%s",s);    
            if(s[0]=='E') break;
            scanf("%d%d%d%d",&x1,&y1,&x2,&y2);    
            --x1; --x2;
            if(y1>y2) {
                swap(x1,x2);
                swap(y1,y2);    
            }
            if(s[0]=='O') seg.change(1,1,x1,y1,x2,y2);
            else if(s[0]=='C') seg.change(0,1,x1,y1,x2,y2);
            else seg.ask(x1,y1,x2,y2);
        }    
        return 0;    
    }
  • 相关阅读:
    02-17 位图验证码(一般处理程序)+AJAX
    02-18 报表
    SQLite 函数大全
    SQLite中的时间日期函数(转)
    DES,AeS加解密,MD5,SHA加密
    suspendlayout
    AES--高级数据加密标准
    C#中Validating和Validated事件
    Net操作Excel(终极方法NPOI)
    decimal,float和double的区别
  • 原文地址:https://www.cnblogs.com/invoid/p/5584169.html
Copyright © 2011-2022 走看看