• [SHOI2008]堵塞的交通traffic(BZOJ1018)


    Link is here

    1018: [SHOI2008]堵塞的交通traffic

    Time Limit: 3 Sec  Memory Limit: 162 MB

    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
     
     
        感觉自己太水了T_T... 先跪舔squarefk大神,祝他这次高考420+60满分虐THU...
        这是一个区间QAQ...
        线段树维护区间连通性的题,方神维护了一个link类{lb,rb,b[2][2]} //左边连通性,右边连通性,中间连通性(如图)
        对于每个区间维护一个link类,和中点的连通性。
        建树时只每个叶子的link类的b[0][0]和b[1][1]显然都是联通的(自己联通自己)
        修改操作分成两种,一种是在一列的,一种是在一行的,讨论下即可。
        查询操作没有什么区别。
        合并操作也没有什么区别,画个图就可以写出来了,但要注意细节QAQ...
     
      ORZ Squarefk 跪跪跪...
        以下是模仿大神的codes:
     1 #include<cstdio>
     2 #include<cstdlib>
     3 #include<cstring>
     4 #include<iostream>
     5 #include<algorithm>
     6 using namespace std;
     7 const int N = 100010;
     8 #define Ch1 (i<<1)
     9 #define Ch2 (i<<1)|1
    10 #define For(i,n) for(int i=1;i<=n;i++)
    11 #define Rep(i,l,r) for(int i=l;i<=r;i++)
    12 
    13 struct Link{
    14     bool lb,rb,b[2][2];
    15 }Left,Right,Mid;
    16 struct tnode{
    17     int l,r,mid;
    18     bool b0,b1;Link b;
    19 }T[N*4];
    20 char op[10];
    21 bool ans;
    22 int n,x1,x2,y1,y2;
    23 
    24 Link Merge(Link Left,Link Right,bool b0,bool b1){
    25     Link merged;
    26     merged.lb =  Left.lb||(( Left.b[0][0])&&( Left.b[1][1])&&(b0)&&(b1)&&(Right.lb));
    27     merged.rb = Right.rb||((Right.b[0][0])&&(Right.b[1][1])&&(b0)&&(b1)&&(Left.rb));
    28     memset(merged.b,false,sizeof(merged.b));
    29     if(b0)  Rep(i,0,1)
    30                Rep(j,0,1) merged.b[i][j] |=  Left.b[i][0] && Right.b[0][j];
    31     if(b1)  Rep(i,0,1)
    32               Rep(j,0,1) merged.b[i][j] |=  Left.b[i][1] && Right.b[1][j];
    33     return merged;
    34 }
    35 
    36 void Build(int l,int r,int i){
    37     T[i].l = l; T[i].r = r; T[i].mid = (l+r)>>1;
    38     if(l==r){
    39         T[i].b.b[0][0] = T[i].b.b[1][1] = true;
    40         return;
    41     }
    42     Build(l,T[i].mid,Ch1); Build(T[i].mid+1,r,Ch2);
    43 }
    44 
    45 Link query(int l,int r,int i){
    46     if(l<=T[i].l&&T[i].r<=r)   return T[i].b;
    47     if(r<=T[i].mid)            return query(l,r,Ch1);
    48     if(l>T[i].mid)                 return query(l,r,Ch2);
    49     return Merge(query(l,r,Ch1),query(l,r,Ch2),T[i].b0,T[i].b1);
    50 }
    51 
    52 void Modify(int i,bool change){
    53     if((x1==x2)&&(y1==T[i].mid)){
    54         if(x1) T[i].b1 = change;else T[i].b0 = change;
    55         T[i].b = Merge(T[Ch1].b,T[Ch2].b,T[i].b0,T[i].b1);
    56     }else     if(T[i].l==T[i].r) 
    57                 T[i].b.lb = T[i].b.rb = T[i].b.b[0][1] = T[i].b.b[1][0] = change;
    58     else{
    59         if(y2>T[i].mid) Modify(Ch2,change);
    60         else            Modify(Ch1,change);
    61         T[i].b = Merge(T[Ch1].b,T[Ch2].b,T[i].b0,T[i].b1);
    62     }
    63 }
    64 
    65 int main(){
    66     scanf("%d",&n);
    67     Build(1,n,1);
    68     for(;;){
    69         scanf("%s",op);
    70         if(!strcmp("Exit",op)) return 0;
    71         scanf("%d%d%d%d",&x1,&y1,&x2,&y2);x1--;x2--;
    72         if(y1>y2) swap(y1,y2),swap(x1,x2);
    73         if(!strcmp("Open",op))  Modify(1,true);
    74         if(!strcmp("Close",op)) Modify(1,false);
    75         if(!strcmp("Ask",op)){
    76             Left  = query(1,y1,1);
    77             Right = query(y2,n,1);
    78             Mid   = query(y1,y2,1);
    79             bool ans = false;
    80             Rep(i,0,1)
    81               Rep(j,0,1)
    82                 if(Mid.b[i][j])
    83                   if((i==x1||Left.rb)&&(j==x2||Right.lb)) ans = true;
    84             if(ans) puts("Y");else puts("N");            
    85         }
    86     }
    87     return 0;
    88 }
    跪跪跪
     
  • 相关阅读:
    转: jsp之c标签
    win10下乌龟git安装和使用
    使用Node.js+Socket.IO搭建WebSocket实时应用
    前端优化
    pyqt5环境搭建
    pandas分页读取excel
    PySpark之RDD操作
    PySpark环境搭建
    Django与Celery最佳实践
    Elasticsearch的安装与简单使用
  • 原文地址:https://www.cnblogs.com/zjdx1998/p/3778614.html
Copyright © 2020-2023  润新知