BZOJ 1018 线段树维护图连通性

Posted on 2016-07-13 21:18  yyjxx2010xyu  阅读(...)  评论(... 编辑 收藏

用8个bool维护即可分别为LURU,LURD,LDRU,LDRD,LULD,RURD,Side[1],Side[2]即可。

Side表示这一块有没有接到右边。Merge一下就可以了。码农题,WA了一次,发现未初始化,就AC了。。

  1 #include <cstdio>
  2 inline int Min(int x,int y) {return x>y?y:x;}
  3 inline void Swap(int &x,int &y) {int t=x;x=y;y=t;}
  4 inline void Get_Int(int &x) 
  5 {
  6     char ch=getchar(); x=0;
  7     while (ch<'0' || ch>'9') ch=getchar();
  8     while (ch>='0' && ch<='9') {x=x*10+ch-'0'; ch=getchar();}
  9 }
 10 //========================================
 11 const int Maxn=100100;
 12 struct Node 
 13 {
 14     bool LURU,LURD,LDRU,LDRD,LULD,RURD,Side[3];
 15 }Tree[Maxn<<2],Null;
 16 int x1,y1,x2,y2,n;
 17 char ch[20];
 18 inline Node Merge(Node L,Node R)
 19 {
 20     Node Ret; Ret=Null;
 21     Ret.Side[1]=R.Side[1],Ret.Side[2]=R.Side[2];
 22     if ((L.LURU&&R.LURU&&L.Side[1]) || (L.LURD&&R.LDRU&&L.Side[2])) Ret.LURU=true;
 23     if ((L.LDRD&&R.LDRD&&L.Side[2]) || (L.LDRU&&R.LURD&&L.Side[1])) Ret.LDRD=true;
 24     if ((L.LURU&&R.LURD&&L.Side[1]) || (L.LURD&&R.LDRD&&L.Side[2])) Ret.LURD=true;
 25     if ((L.LDRD&&R.LDRU&&L.Side[2]) || (L.LDRU&&R.LURU&&L.Side[1])) Ret.LDRU=true;
 26     if (L.LULD || (L.LURU&&L.LDRD&&R.LULD&&L.Side[1]&&L.Side[2])) Ret.LULD=true;
 27     if (R.RURD || (R.LURU&&R.LDRD&&L.RURD&&L.Side[1]&&L.Side[2])) Ret.RURD=true;
 28     return Ret;
 29 }
 30 void Build(int o,int l,int r)
 31 {
 32      
 33     if (l==r)
 34     {
 35         Tree[o].LURU=Tree[o].LDRD=true;
 36         return;
 37     }
 38     int mid=(l+r)>>1;
 39     Build(o<<1,l,mid),Build(o<<1|1,mid+1,r);
 40     Tree[o]=Merge(Tree[o<<1],Tree[o<<1|1]);
 41 }
 42 void Modify_X(int o,int l,int r,int pos,bool kind)
 43 {
 44     if (l==r)
 45     {
 46         Tree[o].LULD=Tree[o].RURD=Tree[o].LURD=Tree[o].LDRU=kind;
 47         return;
 48     }
 49     int mid=(l+r)>>1;
 50     if (pos<=mid) Modify_X(o<<1,l,mid,pos,kind); else Modify_X(o<<1|1,mid+1,r,pos,kind);
 51     Tree[o]=Merge(Tree[o<<1],Tree[o<<1|1]);
 52 }
 53 void Modify_Y(int o,int l,int r,int pos,int x,bool kind)
 54 {
 55     if (l==r)
 56     {
 57         Tree[o].Side[x]=kind;
 58         return;
 59     }
 60     int mid=(l+r)>>1;
 61     if (pos<=mid) Modify_Y(o<<1,l,mid,pos,x,kind); else Modify_Y(o<<1|1,mid+1,r,pos,x,kind);
 62     Tree[o]=Merge(Tree[o<<1],Tree[o<<1|1]);
 63 }
 64 inline void Close()
 65 {
 66     if (x1==x2) Modify_Y(1,1,n,Min(y1,y2),x1,false);
 67     if (y1==y2) Modify_X(1,1,n,y1,false);
 68 }
 69 inline void Open()
 70 {
 71     if (x1==x2) Modify_Y(1,1,n,Min(y1,y2),x1,true);
 72     if (y1==y2) Modify_X(1,1,n,y1,true);
 73 }
 74 Node Query(int o,int l,int r,int p,int q)
 75 {
 76     if (l==p && r==q)
 77     {
 78         Node Ret=Tree[o];
 79         return Ret;
 80     }
 81     int mid=(l+r)>>1;
 82     if (q<=mid) return Query(o<<1,l,mid,p,q);
 83     if (p>=mid+1) return Query(o<<1|1,mid+1,r,p,q);
 84     if (p<=mid && q>=mid+1)
 85         return Merge(Query(o<<1,l,mid,p,mid),Query(o<<1|1,mid+1,r,mid+1,q));
 86 } 
 87 inline bool Check()
 88 {
 89     if (y1>y2) Swap(y1,y2),Swap(x1,x2);  
 90     Node Pre,Suf,Now;
 91     if (y1-1>=1) Pre=Query(1,1,n,1,y1-1); else Pre=Null;
 92     if (y2+1<=n) Suf=Query(1,1,n,y2+1,n); else Suf=Null;
 93     Now=Query(1,1,n,y1,y2);
 94     if (x1==x2) 
 95     {
 96         if ((x1==1) && ((Now.LURU) || (Pre.RURD&&Pre.Side[1]&&Pre.Side[2]&&Now.LDRU) || (Suf.LULD&&Now.Side[1]&&Now.Side[2]&&Now.LURD) || (Pre.RURD&&Suf.LULD&&Now.Side[1]&&Now.Side[2]&&Pre.Side[1]&&Pre.Side[2]&&Now.LDRD)))  return true;
 97         if ((x1==2) && ((Now.LDRD) || (Pre.RURD&&Pre.Side[1]&&Pre.Side[2]&&Now.LURD) || (Suf.LULD&&Now.Side[1]&&Now.Side[2]&&Now.LDRU) || (Pre.RURD&&Suf.LULD&&Now.Side[1]&&Now.Side[2]&&Pre.Side[1]&&Pre.Side[2]&&Now.LURU)))  return true;    
 98     } else
 99     {
100         if ((x1==1 && x2==2) && ((Now.LURD) || (Pre.RURD&&Pre.Side[1]&&Pre.Side[2]&&Now.LDRD) || (Suf.LULD&&Now.Side[1]&&Now.Side[2]&&Now.LURU) || (Pre.RURD&&Suf.LULD&&Now.Side[1]&&Now.Side[2]&&Pre.Side[1]&&Pre.Side[2]&&Now.LDRU)))  return true;
101         if ((x1==2 && x2==1) && ((Now.LDRU) || (Pre.RURD&&Pre.Side[1]&&Pre.Side[2]&&Now.LURU) || (Suf.LULD&&Now.Side[1]&&Now.Side[2]&&Now.LDRD) || (Pre.RURD&&Suf.LULD&&Now.Side[1]&&Now.Side[2]&&Pre.Side[1]&&Pre.Side[2]&&Now.LURD)))  return true;
102     }
103     return false;
104 }
105 inline void Ask() {if (Check()) puts("Y"); else puts("N");}
106 int main()
107 {
108     // freopen("c.in","r",stdin);
109     Get_Int(n); Build(1,1,n);
110     Null.LURU=Null.LURD=Null.LDRU=Null.LDRD=Null.Side[1]=Null.Side[2]=Null.LULD=Null.RURD=false;
111     while (scanf("%s",ch)!=EOF)
112     {
113         if (ch[0]=='E') break;
114         Get_Int(x1),Get_Int(y1),Get_Int(x2),Get_Int(y2);
115         if (ch[0]=='O') Open();
116         if (ch[0]=='C') Close();
117         if (ch[0]=='A') Ask();
118     }
119     return 0;
120 }
C++