bzoj 1018: [SHOI2008]堵塞的交通traffic

由于只有两行,对一个区间可以维护四个角上的连通性 一共6个量,满足区间可加性,用线段树维护,查询时找出3段的量,看是否满足题解上的三种情况之一。

  1 #include<cstdio>
  2 #include<iostream>
  3 #include<cstring>
  4 #include<cstdlib>
  5 #include<cmath>
  6 #include<queue>
  7 #include<algorithm>
  8 #include<vector>
  9 #define M 1000009
 10 #define EPS 1e-10
 11 #define MO 19650827
 12 #define ll long long
 13 using namespace std;
 14 ll read()
 15 {
 16     char ch=getchar();
 17     ll x=0,f=1;
 18     for(;ch<‘0‘||ch>‘9‘;ch=getchar())
 19         if(ch==‘-‘)
 20           f=-1;
 21     for(;ch>=‘0‘&&ch<=‘9‘;ch=getchar())
 22         x=x*10+ch-‘0‘;
 23     return x*f;
 24 }
 25 int n,mp[M];
 26 struct data
 27 {
 28   bool f[6];
 29 }s[10],a[M];
 30 void build(int x,int l,int r)
 31 {
 32   if(l==r)
 33     {
 34       a[x]=s[0];
 35       return;
 36      }
 37   int mid=(l+r)>>1;
 38   build(x*2,l,mid);
 39   build(x*2+1,mid+1,r);
 40 }
 41 int calc(int x,int y)
 42 {
 43   return x*(n-1)+y;
 44 }
 45 data he(data a,data b,int x,int y)
 46 {
 47   data c;
 48   c.f[0]=((a.f[0]&&x&&b.f[0])||(a.f[4]&&y&&b.f[5]));
 49   c.f[1]=((a.f[1]&&y&&b.f[1])||(a.f[5]&&x&&b.f[4]));
 50   c.f[2]=(a.f[2]||(a.f[0]&&x&&b.f[2]&&y&&a.f[1]));
 51   c.f[3]=(b.f[3]||(b.f[0]&&x&&a.f[3]&&y&&b.f[1]));
 52   c.f[4]=((a.f[4]&&y&&b.f[1])||(a.f[0]&&x&&b.f[4]));
 53   c.f[5]=((a.f[5]&&x&&b.f[0])||(a.f[1]&&y&&b.f[5]));
 54   return c;
 55 }
 56 void gai(int x,int l,int r,int x1,int y1,int x2,int c)
 57 {
 58   int mid=(l+r)>>1;
 59   if(x1==x2&&mid==y1)
 60     {
 61       mp[calc(x1,y1)]=c;
 62       a[x]=he(a[x*2],a[x*2+1],mp[calc(0,y1)],mp[calc(1,y1)]);
 63       return;
 64     }
 65   if(l==r)
 66     {
 67       mp[calc(2,y1)]=c;
 68       a[x]=s[c];
 69       return;
 70     }
 71   if(y1<=mid)
 72     gai(x*2,l,mid,x1,y1,x2,c);
 73   else
 74     gai(x*2+1,mid+1,r,x1,y1,x2,c);
 75   a[x]=he(a[x*2],a[x*2+1],mp[calc(0,mid)],mp[calc(1,mid)]);
 76 }
 77 data query(int x,int l,int r,int L,int R)
 78 {
 79   int mid=(l+r)>>1;
 80   if(L<=l&&R>=r)
 81     return a[x];
 82   if(R<=mid)
 83     return query(x*2,l,mid,L,R);
 84   if(L>mid)
 85     return query(x*2+1,mid+1,r,L,R);
 86   return he(query(x*2,l,mid,L,R),query(x*2+1,mid+1,r,L,R),mp[calc(0,mid)],mp[calc(1,mid)]);
 87 }
 88 void xun(int x1,int y1,int x2,int y2)
 89 {
 90   s[2]=query(1,1,n,1,y1);
 91   s[3]=query(1,1,n,y1,y2);
 92   s[4]=query(1,1,n,y2,n);
 93   int ans;
 94   if(x1==x2)
 95     ans=(s[3].f[x1]||(s[2].f[3]&&s[3].f[4+x1^1])||(s[3].f[4+x1]&&s[4].f[2])||(s[2].f[3]&&s[3].f[x1^1]&&s[4].f[2]));
 96   else
 97     ans=(s[3].f[4+x1]||(s[2].f[3]&&s[3].f[x1^1])||(s[3].f[x1]&&s[4].f[2])||(s[2].f[3]&&s[3].f[4+x1^1]&&s[4].f[2]));
 98   if(ans)
 99     printf("Y\n");
100   else
101     printf("N\n");
102 }
103 int main()
104 {
105    s[0]=(data){1,1,0,0,0,0};
106    s[1]=(data){1,1,1,1,1,1};
107    n=read();
108    build(1,1,n);
109    for(;;)
110      {
111        char ch[10];
112        scanf("%s",ch);
113        if(ch[0]==‘E‘)
114          return 0;
115        int x1=read(),y1=read(),x2=read(),y2=read();
116        x1--;
117        x2--;
118        if(y1>y2)
119          {
120            swap(y1,y2);
121            swap(x1,x2);
122          }
123        if(ch[0]==‘O‘)
124          gai(1,1,n,x1,y1,x2,1);
125        if(ch[0]==‘C‘)
126          gai(1,1,n,x1,y1,x2,0);
127        if(ch[0]==‘A‘)
128          xun(x1,y1,x2,y2);
129      }
130    return 0;
131 }
132 
时间: 2024-10-22 06:36:01

bzoj 1018: [SHOI2008]堵塞的交通traffic的相关文章

BZOJ 1018: [SHOI2008]堵塞的交通traffic [线段树 区间信息]

1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 3064  Solved: 1027[Submit][Status][Discuss] Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个城市和3C-2条道路. 小人国的交通

数据结构(线段树):BZOJ 1018: [SHOI2008]堵塞的交通traffic

1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec  Memory Limit: 162 MBSubmit: 2638  Solved: 864 Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个城市和3C-2条道路. 小人国的交通状况非常槽糕.有的时候由于交通堵塞,两座城市之间的道

[BZOJ 1018] [SHOI2008] 堵塞的交通traffic 【线段树维护联通性】

题目链接:BZOJ - 1018 题目分析 这道题就说明了刷题少,比赛就容易跪..SDOI Round1 Day2 T3 就是与这道题类似的..然而我并没有做过这道题.. 这道题是线段树维护联通性的经典模型. 我们线段树的一个节点表示一个区间的联通性,有 6 个 bool 值,表示这个区间的 4 个角上的点之间的联通性. 然后用两个子区间的联通性和两个子区间之间的连边情况合并出整个区间的联通性. 修改某条边时,先在边的数组中修改,然后从这条边所在的点的线段树叶子开始向上 Update . 询问两

[BZOJ 1018][SHOI2008]堵塞的交通traffic(线段树)

Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可 以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个 城市和3C-2条道路. 小人国的交通状况非常槽糕.有的时候由于交通堵塞,两座城市之间的道路会变得不连通, 直到拥堵解决,道路才会恢复畅通.初来咋到的你决心毛遂自荐到交通部某份差事,部长听说你来自一个科技高度 发达的世界,喜出望外地要求你编写一个查询应答系统,以挽救已经病入

BZOJ 1018 SHOI2008 堵塞的交通traffic 线段树

题目大意:给定一张2*n的网格图,多次改变某条边是否可用,多次查询某两个点是否联通 多(yi)年前的我看到这题的第一反应是:这题尼玛能做? 两个点之间的路径可能是这样的: 也可能是这样的: 甚至可能是这样的: 这题能写? 这题其实好写爆了 我们首先忽略第三种情况,假设所有对答案有贡献的边都在两个点的中间 那么我们以每一列为一个叶节点建立线段树 线段树的每个节点开一个二维数组a[2][2] 其中 a[x][y]记录当前区间的左端点的第x行和右端点的第y行是否联通 那么合并如下: 例如,a[0][0

1018: [SHOI2008]堵塞的交通traffic

1018: [SHOI2008]堵塞的交通traffic 链接 分析: 用线段树维护区间的四个端点的联通情况,然后查询的时候,把所有覆盖到的区间合并起来即可. 六种情况左上到右上(左边到右边的情况)……,左上到左下(同一侧相互到达的情况)…… 同一侧相互到达的情况,查询[l,r]是查的不完全.因为还有可能是先往左边走几步,下去,在走回来.这时候,查询一下[1,l]的情况,或起来即可. 代码: 1 #include<cstdio> 2 #include<algorithm> 3 #i

【BZOJ】1018: [SHOI2008]堵塞的交通traffic

http://www.lydsy.com/JudgeOnline/problem.php?id=1018 题意:有2行,每行有c(c<=100000)个城市,则一共有c-1个格子,现在有q(q<=100000)个操作,操作Open和Close是将格子的四个角相邻的城市连边或删边,操作Ask是询问两个城市是否连通 #include <cstdio> #include <cstring> #include <cmath> #include <string&

【SHOI 2008】【BZOJ 1018】堵塞的交通traffic

发现很多有关区间联通问题的题线段树都可以做,不论是1列还是2列.这题的易错点在于两个端点x,y之间的可行路径不一定在区间[x,y]之间,有可能是从其他区间绕过来的,想明白这一点,区间的更新又与1列的情况基本类似,这题就很好做了. code: #include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define mid (l+r)/2 #define lch i<

【BZOJ 1018】 [SHOI2008]堵塞的交通traffic

1018: [SHOI2008]堵塞的交通traffic Time Limit: 3 Sec  Memory Limit: 162 MB Submit: 1811  Solved: 580 [Submit][Status] Description 有一天,由于某种穿越现象作用,你来到了传说中的小人国.小人国的布局非常奇特,整个国家的交通系统可以被看成是一个2行C列的矩形网格,网格上的每个点代表一个城市,相邻的城市之间有一条道路,所以总共有2C个城市和3C-2条道路. 小人国的交通状况非常槽糕.有