zoukankan      html  css  js  c++  java
  • BZOJ 1018 线段树维护图连通性

    用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++
  • 相关阅读:
    Discuz经典函数注释之authcode
    在delphi中,DLL加载时做初始化的Demo
    KERNEL32相关函数
    解析 png 图片的十六进制字符流
    delphi 获取硬盘序列号、cpu号、bios号、网卡号
    封装 INI 文件读写函数
    A窗口消失B窗口弹出
    delphi公用函数
    获取打开文件的PID
    C# cmd调用外部命令
  • 原文地址:https://www.cnblogs.com/yyjxx2010xyu/p/5668234.html
Copyright © 2011-2022 走看看