zoukankan      html  css  js  c++  java
  • BZOJ 1018: [SHOI2008]堵塞的交通traffic(线段树)

    题目:http://www.lydsy.com/JudgeOnline/problem.php?id=1018

    用线段树维护区间连通性,对于每一个区间记录6个域表示(左上,左下)(左上,右上)(右上,右下)(左下,右下)(左上,右下)(左下,右上)的连通情况。

    因为是与相邻点的关系所以维护一个数组表示当前列x与列x+1的连边情况和当前列x的第一行与第二行的连边情况。

    然后就是区间合并。。各种分类讨论。。

    #include<cstring>
    #include<iostream>
    #include<algorithm>
    #include<cstdio>
    #include<queue>
    #include<map>
    #include<vector>
    #define rep(i,l,r) for (int i=l;i<=r;i++)
    #define down(i,l,r) for (int i=l;i>=r;i--)
    #define clr(x,y) memset(x,y,sizeof(x))
    #define ll long long
    #define maxn 100500
    #define mm 998244353
    using namespace std;
    struct data{int b[6],l,r;
    }t[maxn*4];
    int road[maxn][3],n;
    char s[10];
    int read(){
        int x=0,f=1; char ch=getchar();
        while (!isdigit(ch)){if (ch=='-') f=-1; ch=getchar();}
        while (isdigit(ch)){x=x*10+ch-'0'; ch=getchar();}
        return x*f;
    }
    data M(data l,data r){
        data i;
        i.l=l.l; i.r=r.r;
        i.b[0]=(l.b[0])||( ( (l.b[1]&&l.b[3]) || (l.b[4]&&l.b[5]) )&&(road[l.r][0])&&(road[l.r][1])&&(r.b[0]));
        i.b[2]=(r.b[2])||( ( (r.b[1]&&r.b[3]) || (r.b[4]&&r.b[5]) )&&(road[l.r][0])&&(road[l.r][1])&&(l.b[2]));
        i.b[1]=(l.b[1]&&r.b[1]&&road[l.r][0]) || (l.b[4]&&r.b[5]&&road[l.r][1]);
        i.b[3]=(l.b[3]&&r.b[3]&&road[l.r][1]) || (l.b[5]&&r.b[4]&&road[l.r][0]);
        i.b[4]=(l.b[1]&&r.b[4]&&road[l.r][0]) || (l.b[4]&&r.b[3]&&road[l.r][1]);
        i.b[5]=(l.b[5]&&r.b[1]&&road[l.r][0]) || (l.b[3]&&r.b[5]&&road[l.r][1]);
        return i;
    }
    void build(int i,int l,int r){
        t[i].l=l; t[i].r=r; int mid=(l+r)/2;
        if (l==r){ t[i].b[1]=t[i].b[3]=1; return; }
        build(i*2,l,mid); build(i*2+1,mid+1,r);
        t[i]=M(t[i*2],t[i*2+1]);
    }
    void change(int pos,int i){
        int l=t[i].l,r=t[i].r,mid=(l+r)/2;
        if (l==r){
            rep(j,0,5) t[i].b[j]=road[l][2];
            t[i].b[1]=t[i].b[3]=1;
            return;
        }
        if (pos<=mid) change(pos,i*2); else change(pos,i*2+1);
        t[i]=M(t[i*2],t[i*2+1]);
    }
    void change(int x0,int y0,int x1,int y1,int flag){
        if (y0>y1) swap(x0,x1),swap(y0,y1);
        if (x0==x1) {
            if (x0==1) road[y0][0]=flag; else road[y0][1]=flag;
        } else road[y0][2]=flag;
        change(y0,1);
    }
    data ask(int i,int tl,int tr){
        int l=t[i].l,r=t[i].r,mid=(l+r)/2;
        if (l==tl&&r==tr) return t[i];
        if (tr<=mid) return ask(i*2,tl,tr);
        else if (tl>mid) return ask(i*2+1,tl,tr);
        else return M(ask(i*2,tl,mid),ask(i*2+1,mid+1,tr));
    }
    bool query(int x0,int y0,int x1,int y1){
        if (y0>y1) swap(x0,x1),swap(y0,y1);
        data x=ask(1,1,y0),y=ask(1,y0,y1),z=ask(1,y1,n);
        if (x0==x1) {
            if (x0==1){
                if (y.b[1]) return 1;
                if ((x.b[2]||y.b[0])&&(y.b[2]||z.b[0])&&y.b[3]) return 1;
                if ((y.b[4])&&(y.b[2]||z.b[0])) return 1;
                if ((y.b[5])&&(x.b[2]||y.b[0])) return 1;
                return 0;
            }
            else {
                if (y.b[3]) return 1;
                if ((x.b[2]||y.b[0])&&(y.b[2]||z.b[0])&&y.b[1]) return 1;
                if ((y.b[5])&&(y.b[2]||z.b[0])) return 1;
                if ((y.b[4])&&(x.b[2]||y.b[0])) return 1;
                return 0;
            }
        }
        else {
            if (x0==1){
                if (y.b[4]) return 1;
                if ((x.b[2]||y.b[0])&&y.b[3]) return 1;
                if ((x.b[2]||y.b[0])&&(y.b[2]||z.b[0])&&y.b[5]) return 1;
                if ((y.b[2]||z.b[0])&&y.b[1]) return 1;
                return 0;
            }
            else {
                if (y.b[5]) return 1;
                if ((x.b[2]||y.b[0])&&y.b[1]) return 1;
                if ((x.b[2]||y.b[0])&&(y.b[2]||z.b[0])&&y.b[4]) return 1;
                if ((y.b[2]||z.b[0])&&y.b[3]) return 1;
                return 0;
            }
        }
         
    }
    int main(){
        n=read();
        build(1,1,n);
        int x0,x1,y0,y1;
        while (1){
            scanf("%s",s);
            if (s[0]=='E') break;
            x0=read(); y0=read(); x1=read(); y1=read();
            if (s[0]=='O') change(x0,y0,x1,y1,1);
            else if (s[0]=='C') change(x0,y0,x1,y1,0);
            else printf("%c
    ",query(x0,y0,x1,y1)?'Y':'N');
        }
        return 0;
    }
  • 相关阅读:
    Java:API文档;文档注释中的javadoc标记;官方API;自己动手给项目建一个API文档
    Java:配置环境(Mac)——MySQL
    Java:配置环境(Mac)——Tomcat
    Java:配置环境(Mac)——Eclipse;修改JDK版本后,Eclipse打不开
    Java:配置环境(Mac)——JDK
    Git:九、删除项目
    Git:修改Git Bash默认打开位置(win10)
    操作系统:diskpart常用指令(使用diskpart实现分区管理)
    人生第一次离职
    C++ std::thread概念介绍
  • 原文地址:https://www.cnblogs.com/ctlchild/p/5094813.html
Copyright © 2011-2022 走看看