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
");
100   else
101     printf("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 
原文地址:https://www.cnblogs.com/xiw5/p/5651727.html