[Wc2006]水管局长数据加强版 LCA&RMQ

系统 1942 0

参考论文:  郭华阳《RMQ与LCA问题》 的解法.

通过构建最小生成树,然后转换成 寻找最近公共祖先来求解, 逆序处理询问,将删除改成添加边.

代码在BZOJ上WA了.暂时未找到原因, 先放着... 不过有看到用splay, 动态树等做的..

        #include<cstdio>
        
          

#include
        
        <cstdlib>
        
          

#include
        
        <cstring>
        
          

#include
        
        <algorithm>
        
          

#include
        
        <map>
        
          

#include
        
        <vector>


        
          using
        
        
          namespace
        
        
           std;


        
        
          const
        
        
          int
        
         N = (
        
          int
        
        )1e5+
        
          10
        
        
          ;


        
        
          const
        
        
          int
        
         M = (
        
          int
        
        )1e6+
        
          10
        
        
          ;


        
        
          const
        
        
          int
        
         maxn = 
        
          5
        
        *
        
          N;


        
        
          int
        
        
           n, m, Q_num;


        
        
          struct
        
        
           node{

    
        
        
          int
        
        
           a, b, t;

    
        
        
          bool
        
        
          operator
        
         < (
        
          const
        
         node &tmp) 
        
          const
        
        
          {

        
        
        
          return
        
         t <
        
           tmp.t;

    }

}edge[M];


        
        
          struct
        
        
           Query{

    
        
        
          int
        
        
           k,a,b;

}Q[N];



map
        
        < pair<
        
          int
        
        ,
        
          int
        
        >, 
        
          int
        
         >
        
           mp;

vector
        
        <
        
          int
        
        > S[
        
          2
        
        *N+
        
          10
        
        
          ];




        
        
          int
        
        
           getint(){

    
        
        
          char
        
         ch =
        
           getchar();

    
        
        
          for
        
        (; ch > 
        
          '
        
        
          9
        
        
          '
        
         || ch < 
        
          '
        
        
          0
        
        
          '
        
        ; ch =
        
           getchar() );

    
        
        
          int
        
         tmp = 
        
          0
        
        
          ;

    
        
        
          for
        
        (; ch > 
        
          '
        
        
          0
        
        
          '
        
         && ch < 
        
          '
        
        
          9
        
        
          '
        
        ; ch =
        
           getchar() )

        tmp 
        
        = tmp*
        
          10
        
         + ch - 
        
          '
        
        
          0
        
        
          '
        
        
          ;

    
        
        
          return
        
        
           tmp;

}




        
        
          int
        
        
           st[maxn], top;


        
        
          bool
        
        
           vis[M];




        
        
          int
        
         find(
        
          int
        
        
           x){

    
        
        
          return
        
         st[x] == x ?
        
           x : find(st[x]);

}




        
        
          void
        
        
           debug(){

    printf(
        
        
          "
        
        
          n = %d, m = %d, Q_num = %d\n
        
        
          "
        
        
          , n, m, Q_num );

    printf(
        
        
          "
        
        
          Edge:\n
        
        
          "
        
        
          );

    
        
        
          for
        
        (
        
          int
        
         i = 
        
          0
        
        ; i < m; i++
        
          )

        printf(
        
        
          "
        
        
          (%d,%d,t=%d)\n
        
        
          "
        
        
          , edge[i].a, edge[i].b, edge[i].t );

    printf(
        
        
          "
        
        
          Query:\n
        
        
          "
        
        
          );

    
        
        
          for
        
        (
        
          int
        
         i = 
        
          0
        
        ; i < Q_num; i++
        
          )

        printf(
        
        
          "
        
        
          k=%d,(%d,%d)\n
        
        
          "
        
        
          , Q[i].k, Q[i].a, Q[i].b );



}


        
        
          void
        
        
           input(){

    n 
        
        = getint(); m = getint(); Q_num =
        
           getint();

        

    
        
        
          for
        
        (
        
          int
        
         i = 
        
          0
        
        ; i < m; i++){ 
        
          //
        
        
           Edge infomation
        
        

        edge[i].a =
        
           getint();

        edge[i].b 
        
        =
        
           getint();

        edge[i].t 
        
        =
        
           getint();

    }

    
        
        
          for
        
        (
        
          int
        
         i = 
        
          0
        
        ; i < Q_num; i++){ 
        
          //
        
        
           Query 
        
        

        Q[i].k =
        
           getint();

        Q[i].a 
        
        =
        
           getint();

        Q[i].b 
        
        =
        
           getint();

    }

    sort( edge, edge
        
        +m ); 
        
          //
        
        
           sort by t desc
        
        
          for
        
        (
        
          int
        
         i = 
        
          0
        
        ; i < m; i++) 
        
          //
        
        
           index
        
        

        mp[ make_pair( edge[i].a, edge[i].b ) ] =
        
           

            mp[ make_pair( edge[i].b, edge[i].a ) ] 
        
        =
        
           i;

    
        
        
          for
        
        (
        
          int
        
         i = 
        
          0
        
        ; i < Q_num; i++
        
          ){

        
        
        
          if
        
        ( Q[i].k == 
        
          2
        
        
           )    

            vis[ mp[make_pair(Q[i].a, Q[i].b)] ] 
        
        = 
        
          true
        
        
          ;    

    }    


        
        
          //
        
        
              for(int i = 0; i < m; i++)


        
        
          //
        
        
                  printf("%d ", vis[i] ); puts("");
        
        
          }




        
        
          int
        
        
           val[maxn];


        
        
          int
        
        
           pos[maxn], dep[maxn], vec[maxn], idx;


        
        
          int
        
         dp[maxn][
        
          50
        
        
          ];




        
        
          void
        
         dfs(
        
          int
        
         u,
        
          int
        
        
           d){

    dep[
        
        ++idx] = d; vec[idx] =
        
           u;    

    
        
        
          if
        
        ( pos[u] == -
        
          1
        
         ) pos[u] =
        
           idx;

    dep[idx] 
        
        =
        
           d;

    
        
        
          for
        
        (
        
          int
        
         i = 
        
          0
        
        ; i < (
        
          int
        
        )S[u].size(); i++
        
          ){

        dfs( S[u][i], d
        
        +
        
          1
        
        
           );    

        dep[
        
        ++idx] = d;    vec[idx] =
        
           u;    

    }

}




        
        
          void
        
        
           print(){

    printf(
        
        
          "
        
        
          Top = %d\n
        
        
          "
        
        
          , top);

    
        
        
          for
        
        (
        
          int
        
         i = 
        
          1
        
        ; i <= top; i++) printf(
        
          "
        
        
          pos[%d] = %d, val[%d] = %d\n
        
        
          "
        
        
          , i, pos[i], i, val[i]);



    printf(
        
        
          "
        
        
          idx = %d\n
        
        
          "
        
        
          , idx);

    
        
        
          for
        
        (
        
          int
        
         i = 
        
          1
        
        ; i <= idx; i++
        
          )

        printf(
        
        
          "
        
        
          i = %d, vec[%d] = %d, dep[%d] = %d\n
        
        
          "
        
        
          , i, i, vec[i], i, dep[i] );    



}


        
        
          void
        
        
           predeal(){

    
        
        
          for
        
        (
        
          int
        
         i = 
        
          0
        
        ; i < 
        
          2
        
        *n+
        
          10
        
        ; i++
        
          )

        st[i] 
        
        =
        
           i, S[i].clear();    

    top 
        
        =
        
           n;

    
        
        
          for
        
        (
        
          int
        
         i = 
        
          0
        
        ; i < m; i++
        
          ){

        
        
        
          if
        
        ( vis[ mp[ make_pair( edge[i].a, edge[i].b )  ] ] == 
        
          false
        
        
           ){

            
        
        
          int
        
         a = edge[i].a, b = edge[i].b, t =
        
           edge[i].t;

            
        
        
          int
        
         x = find(a), y =
        
           find(b);    

        
        
        
          //
        
        
              printf("(%d,%d): x = %d, y = %d\n",a,b, x, y );    
        
        
          if
        
        ( x !=
        
           y ){

                st[x] 
        
        = st[y] = ++
        
          top;

                val[top] 
        
        =
        
           t;

                S[top].push_back(x), S[top].push_back(y);    

            }

        }    

    }



    
        
        
          for
        
        (
        
          int
        
         i = 
        
          1
        
        ; i <= top; i++
        
          ) 

        pos[i] 
        
        = -
        
          1
        
        
          ; 

    idx 
        
        = 
        
          0
        
        
          ;

    dfs( top, 
        
        
          0
        
        
           );    



    
        
        
          //
        
        
          print();

    
        
        
          //
        
        
           init RMQ
        
        
          for
        
        (
        
          int
        
         i = 
        
          1
        
        ; i <= idx; i++
        
          )

        dp[i][
        
        
          0
        
        ] =
        
           i;

    
        
        
          for
        
        (
        
          int
        
         j = 
        
          1
        
        ; (
        
          1
        
        <<j) <= idx; j++
        
          ){

        
        
        
          for
        
        (
        
          int
        
         i = 
        
          1
        
        ; i+(
        
          1
        
        <<j)-
        
          1
        
         <= idx; i++
        
          ){

            
        
        
          //
        
        
           dp[i][j] = min( dp[i][j-1], dp[i+(1<<(j-1))][j-1] );
        
        
          if
        
        ( dep[ dp[i][j-
        
          1
        
        ] ] < dep[ dp[i+(
        
          1
        
        <<(j-
        
          1
        
        ))][j-
        
          1
        
        
          ] ] )

                dp[i][j] 
        
        = dp[i][j-
        
          1
        
        
          ];

            
        
        
          else
        
         dp[i][j] = dp[i+(
        
          1
        
        <<(j-
        
          1
        
        ))][j-
        
          1
        
        
          ];

        }    

    }

}


        
        
          int
        
         RMQ_find(
        
          int
        
         l,
        
          int
        
        
           r){

    
        
        
          int
        
         d = r-l+
        
          1
        
        , k = 
        
          0
        
        
          ;

    
        
        
          while
        
        ( (
        
          1
        
        <<(k+
        
          1
        
        )) < d ) k++
        
          ;


        
        
          //
        
        
              printf("RMQ: k = %d\n", k );


        
        
          //
        
        
              printf("RMQ: L = %d, R = %d\n", dp[l][k] , dp[r-(1<<k)+1][k] );
        
        
          if
        
        ( dep[ dp[l][k] ] < dep[ dp[r-(
        
          1
        
        <<k)+
        
          1
        
        ][k] ] ) 
        
          return
        
        
           dp[l][k];

    
        
        
          return
        
         dp[ r-(
        
          1
        
        <<k)+
        
          1
        
        
           ][k];

}




        
        
          int
        
        
           ans[M], ans_cnt;




        
        
          void
        
        
           solve(){

    
        
        
          int
        
         ans_cnt = 
        
          0
        
        
          ;

    predeal();

    
        
        
          for
        
        (
        
          int
        
         i = Q_num-
        
          1
        
        ; i >= 
        
          0
        
        ; i--
        
           ){ 

        
        
        
          if
        
        ( Q[i].k == 
        
          1
        
        
           ){

            
        
        
          int
        
         l = pos[ Q[i].a ], r =
        
           pos[ Q[i].b ];

        
        
        
          //
        
        
              printf("(a=%d,b=%d),(l=%d,r=%d)\n", Q[i].a, Q[i].b, l, r);    
        
        
          if
        
        ( l >
        
           r ) swap( l, r );

            
        
        
          int
        
         pt = RMQ_find(l,r);  
        
          //
        
        
          printf("pt = %d\n", pt );    
        
        

            ans[ ans_cnt++ ] =
        
           val[ vec[pt] ];

        }

        
        
        
          else
        
        
          {

            
        
        
          //
        
        
           Q[i].k == 2 
        
        

            vis[ mp[ make_pair( Q[i].a,Q[i].b ) ] ] = 
        
          false
        
        
          ;

            predeal(); 
        
        
          //
        
        
           restructrue the min genaration tree
        
        
                  }

    
        
        
          //
        
        
              puts("******************************************************");    
        
        
              }

    
        
        
          for
        
        (
        
          int
        
         i = ans_cnt-
        
          1
        
        ; i >= 
        
          0
        
        ; i--
        
           ){

        printf(
        
        
          "
        
        
          %d\n
        
        
          "
        
        
          , ans[i] );    

    }

}




        
        
          int
        
        
           main(){

    freopen(
        
        
          "
        
        
          1.in
        
        
          "
        
        ,
        
          "
        
        
          r
        
        
          "
        
        
          ,stdin);



    input();

    solve();



    
        
        
          return
        
        
          0
        
        
          ;

}
        
      
View Code

 

[Wc2006]水管局长数据加强版 LCA&RMQ


更多文章、技术交流、商务合作、联系博主

微信扫码或搜索:z360901061

微信扫一扫加我为好友

QQ号联系: 360901061

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描下面二维码支持博主2元、5元、10元、20元等您想捐的金额吧,狠狠点击下面给点支持吧,站长非常感激您!手机微信长按不能支付解决办法:请将微信支付二维码保存到相册,切换到微信,然后点击微信右上角扫一扫功能,选择支付二维码完成支付。

【本文对您有帮助就好】

您的支持是博主写作最大的动力,如果您喜欢我的文章,感觉我的文章对您有帮助,请用微信扫描上面二维码支持博主2元、5元、10元、自定义金额等您想捐的金额吧,站长会非常 感谢您的哦!!!

发表我的评论
最新评论 总共0条评论