• BZOJ 1018 堵塞的交通


    Description

    有一天,由于某种穿越现象作用,你来到了传说中的小人国。小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个城市和3C-2条道路。 小人国的交通状况非常槽糕。有的时候由于交通堵塞,两座城市之间的道路会变得不连通,直到拥堵解决,道路才会恢复畅通。初来咋到的你决心毛遂自荐到交通部某份差事,部长听说你来自一个科技高度发达的世界,喜出望外地要求你编写一个查询应答系统,以挽救已经病入膏肓的小人国交通系统。 小人国的交通部将提供一些交通信息给你,你的任务是根据当前的交通情况回答查询的问题。交通信息可以分为以下几种格式: Close r1 c1 r2 c2:相邻的两座城市(r1,c1)和(r2,c2)之间的道路被堵塞了; Open r1 c1 r2 c2:相邻的两座城市(r1,c1)和(r2,c2)之间的道路被疏通了; Ask r1 c1 r2 c2:询问城市(r1,c1)和(r2,c2)是否连通。如果存在一条路径使得这两条城市连通,则返回Y,否则返回N;

    Input

    第一行只有一个整数C,表示网格的列数。接下来若干行,每行为一条交通信息,以单独的一行“Exit”作为结束。我们假设在一开始所有的道路都是堵塞的。 对30%测试数据,我们保证C小于等于1000,信息条数小于等于1000; 对100%测试数据,我们保证 C小于等于100000,信息条数小于等于100000。

    Output

    对于每个查询,输出一个“Y”或“N”。

    Sample Input

    2
    Open 1 1 1 2
    Open 1 2 2 2
    Ask 1 1 2 2
    Ask 2 1 2 2
    Exit

    Sample Output

    Y
    N

    HINT

     

    Source

    一道很恶心的数据结构题,但是数据结构却很简单,就是一颗裸的线段树。然而,用线段树维护连通性却很恶心(因为它只有相邻的两个点之间有连边)。我的线段树维护了8个域——左右,上下,对角,中间。慢慢写,反正我是写醉了。

    奉劝:(代码仅限对拍,莫看莫看)

      1 #include<iostream>
      2 #include<cstdio>
      3 #include<cstdlib>
      4 using namespace std;
      5 
      6 #define maxn 100010
      7 int n;
      8 struct node
      9 {
     10     int lc,rc,l,r;
     11     bool u[3]; //左上-左下    右上-右下
     12     bool v[3]; //左上-右上    左下-右下
     13     bool w[3]; //左下-右上    左上-右下
     14     bool t[3]; //中间的两个
     15 };
     16 struct SEG
     17 {
     18     int cnt; node tree[maxn*8];
     19     
     20     inline void updata(int now,bool flag)
     21     {
     22         tree[now].w[1] = tree[now].w[2] = false;
     23         if (!flag) if (tree[now].l != tree[now].r) tree[now].u[1] = tree[now].u[2] = false,tree[now].v[1] = tree[now].v[2] = false;
     24         int lc = tree[now].lc,rc = tree[now].rc; bool sign = false;
     25         do
     26         {
     27             sign = false;
     28             if (!tree[now].u[1])
     29             {
     30                 if (tree[now].v[1]&&tree[now].w[1])
     31                     tree[now].u[1] = true,sign = true;
     32                 else if (tree[now].v[2]&&tree[now].w[2])
     33                     tree[now].u[1] = true,sign = true;
     34                 else if (tree[now].u[2]&&tree[now].v[1]&&tree[now].v[2])
     35                     tree[now].u[1] = true,sign = true;
     36                 else if (tree[lc].u[1]) tree[now].u[1] = true,sign = true;
     37             }
     38             if (!tree[now].u[2])
     39             {
     40                 if (tree[now].v[1]&&tree[now].w[2])
     41                     tree[now].u[2] = true,sign = true;
     42                 else if (tree[now].v[2]&&tree[now].w[1])
     43                     tree[now].u[2] = true,sign = true;
     44                 else if (tree[now].u[1]&&tree[now].v[1]&&tree[now].v[2])
     45                     tree[now].u[2] = true,sign = true;
     46                 else if (tree[rc].u[2]) tree[now].u[2] = true,sign = true;
     47             }
     48             if (!tree[now].v[1])
     49             {
     50                 if (tree[now].r - tree[now].l == 1 && tree[now].t[1])
     51                     tree[now].v[1] = true,sign = true;
     52                 else if (tree[now].u[1]&&tree[now].w[1])
     53                     tree[now].v[1] = true,sign = true;
     54                 else if (tree[now].u[2]&&tree[now].w[2])
     55                     tree[now].v[1] = true,sign = true;
     56                 else if (tree[lc].v[1]&&tree[rc].v[1]&&tree[now].t[1])
     57                     tree[now].v[1] = true,sign = true;
     58                 else if (tree[lc].w[2]&&tree[now].t[2]&&tree[rc].w[1])
     59                     tree[now].v[1] = true,sign = true;
     60             }
     61             if (!tree[now].v[2])
     62             {
     63                 if (tree[now].r - tree[now].l == 1 && tree[now].t[2])
     64                     tree[now].v[2] = true,sign = true;
     65                 if (tree[now].u[1]&&tree[now].w[2])
     66                     tree[now].v[2] = true,sign = true;
     67                 else if (tree[now].u[2]&&tree[now].w[1])
     68                     tree[now].v[2] = true,sign = true;
     69                 else if (tree[lc].v[2]&&tree[rc].v[2]&&tree[now].t[2])
     70                     tree[now].v[2] = true,sign = true;
     71                 else if (tree[lc].w[1]&&tree[now].t[1]&&tree[rc].w[2])
     72                     tree[now].v[2] = true,sign = true;
     73             }
     74             if (!tree[now].w[1])
     75             {
     76                 if (tree[now].u[1]&&tree[now].v[1])
     77                     tree[now].w[1] = true,sign = true;
     78                 else if (tree[now].u[2]&&tree[now].v[2])
     79                     tree[now].w[1] = true,sign = true;
     80                 else if (tree[lc].w[1]&&tree[now].t[1]&&tree[rc].v[1])
     81                     tree[now].w[1] = true,sign = true;
     82                 else if (tree[lc].v[2]&&tree[now].t[2]&&tree[now].w[1])
     83                     tree[now].w[1] = true,sign = true;
     84             }
     85             if (!tree[now].w[2])
     86             {
     87                 if (tree[now].u[1]&&tree[now].v[2])
     88                     tree[now].w[2] = true,sign = true;
     89                 else if (tree[now].u[2]&&tree[now].v[1])
     90                     tree[now].w[2] = true,sign = true;
     91                 else if (tree[lc].w[2]&&tree[now].t[2]&&tree[rc].v[2])
     92                     tree[now].w[2] = true,sign = true;
     93                 else if (tree[lc].v[1]&&tree[now].t[1]&&tree[rc].w[2])
     94                     tree[now].w[2] = true,sign = true;
     95             }
     96         }
     97         while (sign);
     98         if (tree[now].l == tree[now].r)
     99             tree[now].w[1] = tree[now].w[2] = false;
    100     }
    101     
    102     inline int build(int l,int r)
    103     {
    104         int now = ++cnt,mid = (l + r) >> 1;
    105         tree[now].l = l; tree[now].r = r;
    106         if (l == r)
    107         {
    108             tree[now].v[1] = tree[now].v[2] = true;
    109             updata(now,1);
    110             return now;
    111         }
    112         tree[now].lc = build(l,mid);
    113         tree[now].rc = build(mid+1,r);
    114         updata(now,1);
    115         return now;
    116     }
    117 
    118     inline bool ask(int a1,int b1,int a2,int b2,int now)
    119     {
    120         if (a1 == a2 && b1 == b2) return true;
    121         int l = tree[now].l,r = tree[now].r,lc = tree[now].lc,rc = tree[now].rc,mid = (l + r) >> 1;
    122         if (b1 == l&&b2 == r)
    123         {
    124             if (a1 == a2 && tree[now].v[a1]) return true;
    125             if (a1 != a2)
    126             {
    127                 if (a1 == 1 && tree[now].w[2]) return true;
    128                 if (a1 == 2 && tree[now].w[1]) return true;
    129                 if (l == r && tree[now].u[1]) return true; 
    130             }
    131         }
    132         else if (b2 <= mid && ask(a1,b1,a2,b2,lc)) return true;
    133         else if (b1 > mid && ask(a1,b1,a2,b2,rc)) return true;
    134         else if (mid >= b1 && mid < b2 && tree[now].t[1]&&ask(a1,b1,1,mid,lc)&&ask(1,mid+1,a2,b2,rc)) return true;
    135         else if (mid >= b1 && mid < b2 && tree[now].t[2]&&ask(a1,b1,2,mid,lc)&&ask(2,mid+1,a2,b2,rc)) return true;
    136         else if (a1 != a2 && tree[now].t[1] && tree[now].t[2])
    137         {
    138             if (b2 <= mid) return tree[rc].u[1]&&ask(a1,b1,a1,mid,lc)&&ask(a2,b2,a2,mid,lc);
    139             else if (b1 > mid) return tree[lc].u[2]&&ask(a1,mid+1,a1,b1,rc)&&ask(a2,mid+1,a2,b2,rc);
    140         }
    141         else if (a1 == a2 && tree[now].t[1]&&tree[now].t[2])
    142         {
    143             if (b2 <= mid)
    144                 return tree[rc].u[1]&&ask(a1,b1,((a1-1)^1)+1,b1,lc)&&ask(((a1-1)^1)+1,b1,((a1-1)^1)+1,mid,lc)&&ask(a2,b2,a2,mid,lc);
    145             else if (b1 > mid)
    146                 return tree[lc].u[2]&&ask(a1,b2,((a1-1)^1)+1,b2,rc)&&ask(((a1-1)^1)+1,mid+1,((a1-1)^1)+1,b2,rc)&&ask(a2,mid+1,a2,b1,rc);
    147         }
    148         return false;
    149     }
    150     
    151     inline void modify(int a1,int b1,int a2,int b2,int now,bool sign)
    152     {
    153         int l = tree[now].l,r = tree[now].r,lc = tree[now].lc,rc = tree[now].rc,mid = (l + r) >> 1;
    154         bool flag = false;
    155         if (a1 == a2)    //处在同一行上
    156         {
    157             if (b1 == mid && b2 == mid + 1)
    158                 tree[now].t[a1] = sign,flag = sign;
    159             else if (b1 <= mid) modify(a1,b1,a2,b2,lc,sign);
    160             else modify(a1,b1,a2,b2,rc,sign);
    161         }
    162         else             //处在同一列上
    163         {
    164             if (l == r) tree[now].u[1] = tree[now].u[2] = sign,flag = true;
    165             else if (b1 <= mid) modify(a1,b1,a2,b2,lc,sign);
    166             else modify(a1,b1,a2,b2,rc,sign);
    167         }
    168         updata(now,flag|sign);
    169         return;
    170     }    
    171 }seg;
    172 
    173 inline int read()
    174 {
    175     int x=0,f=1; char ch=getchar();
    176     while(ch<'0'||ch>'9') { if(ch=='-')f=-1; ch=getchar(); }
    177     while(ch>='0'&&ch<='9') { x=x*10+ch-'0'; ch=getchar(); }
    178     return x * f;
    179 }
    180 
    181 int main()
    182 {
    183     freopen("1018.in","r",stdin);
    184     freopen("1018.out","w",stdout);
    185     n = read();
    186     seg.build(1,n);
    187     char opt[10]; int a1,a2,b1,b2;
    188     do
    189     {
    190         scanf("%s ",opt); 
    191         if (opt[0] == 'E') break;
    192         a1 = read(); b1 = read(); a2 = read(); b2 = read();
    193         if (b1 > b2) swap(a1,a2),swap(b1,b2);
    194         if (opt[0] == 'A')
    195         {
    196             if (seg.ask(a1,b1,a2,b2,1)) printf("Y
    ");
    197             else printf("N
    ");
    198         }
    199         else if (opt[0] == 'O') seg.modify(a1,b1,a2,b2,1,true);
    200         else seg.modify(a1,b1,a2,b2,1,false); 
    201     }
    202     while (true);
    203     return 0;
    204 }
    View Code
  • 相关阅读:
    delphi 如何让ScrollBox的内容与滚动条一起实时滚动
    C# Wpf集合双向绑定
    C# Wpf异步修改UI,多线程修改UI(二)
    C# 自定义线程修改UI(一)
    WPF FindName()查找命名注册的元素
    数据绑定
    WPF绑定Binding及模式
    WPF-Binding的源
    WPF-Binding对数据的检验
    WPF-数据转换
  • 原文地址:https://www.cnblogs.com/mmlz/p/4266447.html
Copyright © 2020-2023  润新知