HDU 3078 Network

简单的  RMQ;  先预处理得到  所有 节点的 公共祖先  和  dfs 得到所有节点的父亲节点;  然后  询问时,从自己出发向上找父亲, 然后  得到所有的节点;排序一下

不知道  这题这样也能过;为什么不会超时啊???????????;

  1 #include<iostream>
  2 #include<cstring>
  3 #include<algorithm>
  4 #include<cmath>
  5 #include<stdio.h>
  6 #include<vector>
  7 using namespace std;
  8 const int maxn = 80010;
  9 struct date{
 10    int v,next;
 11 }edge[maxn<<1]; int total,head[maxn];
 12 int N,Q,node[maxn],fath[maxn];
 13 void add_edge( int u,int v ){
 14     edge[total].v = v;
 15     edge[total].next = head[u];
 16     head[u] = total++;
 17 }
 18 bool vis[maxn]; int dep[maxn<<1],sta[maxn<<1],tab[maxn<<1],dp[maxn<<1][20],num;
 19 void dfs1( int son,int fa ){
 20     vis[son] = true; fath[son] = fa;
 21     for( int i = head[son]; i != -1; i = edge[i].next ){
 22         int v = edge[i].v;
 23         if( !vis[v] )dfs1( v,son );
 24     }
 25 }
 26 void LCA( int son,int deep ){
 27     dep[num] = deep; sta[son] = num; tab[num] = son;   num++; vis[son] = true;
 28     for( int i = head[son]; i != -1; i = edge[i].next ){
 29         int v = edge[i].v;
 30         if( !vis[v] ){ LCA( v,deep+1 ); dep[num] = deep; tab[num] = son; num++; }
 31     }
 32 }
 33 int work( int n1,int n2 ){
 34    if( dep[n1] < dep[n2] )return n1;
 35    return n2;
 36 }
 37 void RMQ( ){
 38     for( int i = 1; i <= num; i++ )dp[i][0] = i;
 39     for( int i = 1; (1<<i) <= num; i++ ){
 40         for( int j = 1; j - 1 + (1<<i) <= num; j++ )
 41         dp[j][i] = work( dp[j][i-1], dp[j+(1<<(i-1))][i-1] );
 42     }
 43 }
 44 int query( int L,int R ){
 45     int k = 0;
 46     while( (1<<(k+1)) <= R-L+1 )k++;
 47     return tab[work( dp[L][k],dp[R-(1<<k)+1][k] )];
 48 }
 49 vector<int>vv;
 50 bool cmp( int a,int b ){
 51    return a > b;
 52 }
 53 void DO( int u,int v,int fa,int k ){
 54     vv.clear();
 55     while( u != fa ){
 56        vv.push_back( node[u] );
 57        u = fath[u];
 58     }
 59     while( v != fa  ){
 60        vv.push_back( node[v] );
 61        v = fath[v];
 62     }
 63     vv.push_back( node[fa] ); sort( vv.begin(),vv.end(),cmp );
 64     //for( int i = 0; i < vv.size(); i++ )cout<<vv[i]<<endl;
 65     if( vv.size() < k )puts("invalid request!");
 66     else printf("%d\n",vv[k-1]);
 67 }
 68 int main(){
 69       while( scanf("%d%d",&N,&Q) != EOF ){
 70           memset( head,-1,sizeof(head) ); total = 0;
 71           for( int i = 0; i <= N; i++ )fath[i] = i;
 72           for( int i = 1; i <= N; i++ )scanf("%d",&node[i]);
 73           for( int i = 1; i <  N; i++ )
 74           {
 75               int u,v; scanf("%d%d",&u,&v);
 76               add_edge( u,v );
 77               add_edge( v,u );
 78           }
 79           memset( vis,0,sizeof(vis) );
 80           dfs1( 1,-1 ); fath[1] = 1;
 81           memset( vis,0,sizeof(vis) );num = 1;
 82           LCA( 1,1 );
 83           //for( int i = 1; i < num; i++ )
 84           //cout<<i<<" "<<dep[i]<<" "<<tab[i]<<endl;
 85           num--;  RMQ( );
 86           while( Q-- ){
 87                int k,u,v; scanf("%d%d%d",&k,&u,&v);
 88                if( k == 0 ){ node[u] = v; continue; }
 89                //cout<<node[4]<<endl;
 90                if( sta[u] > sta[v] )swap( u,v );
 91                //cout<<query( sta[u],sta[v] )<<endl;
 92                DO( u,v,query( sta[u],sta[v] ),k );
 93           }
 94       }
 95       return 0;
 96 }
 97 /*
 98 
 99 7 100
100 5 1 4 2 4 3 6
101 1 2
102 1 3
103 1 4
104 2 5
105 3 6
106 4 7
107 
108 */
View Code

 

posted on 2013-10-03 15:55  浪舟  阅读(247)  评论(0编辑  收藏  举报

导航