简单的 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 ",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 */