题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=3078
题目大意:给出n个节点,n-1条边,q次询问。每个节点都有自己的值。然后是n-1条边。之后是q次查询,有两种状态,k==0,将a的值赋为b,k>0查询a~b最短路上面第k大的值。
思路:正解不会,看着测试数据非常水,就LCA,暴力排序,O(q*n*logn):24*1e8*longn的复杂度,1ms,这就过了?果然还是测试数据水啊。
ACCode:
// luogu-judger-enable-o2
//#pragma comment(linker, "/STACK:1024000000,1024000000")
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<map>
#include<set>
#include<deque>
#include<queue>
#include<stack>
#include<bitset>
#include<string>
#include<fstream>
#include<iostream>
#include<algorithm>
using namespace std;
#define ll long long
#define Pair pair<ll,ll>
//#define max(a,b) (a)>(b)?(a):(b)
//#define min(a,b) (a)<(b)?(a):(b)
#define clean(a,b) memset(a,b,sizeof(a))// 水印
//std::ios::sync_with_stdio(false);
// register
const int MAXN=8e4+10;
const int INF32=0x3f3f3f3f;
const ll INF64=0x3f3f3f3f3f3f3f3f;
const ll MOD=1e9+7;
const double EPS=1.0e-8;
const double PI=acos(-1.0);
struct Node{
ll v,val,nxt;
Node(ll _v=0,ll _val=0,ll _nxt=0){
v=_v;val=_val;nxt=_nxt;
}
};
Node Edge[MAXN<<2];
ll Head[MAXN],Ecnt;
ll Fa[MAXN][30],Len[MAXN][30];
ll Deep[MAXN],Delay[MAXN];
ll Ans[MAXN],tot;
ll n,m,q;
void Intt(){
clean(Head,-1);Ecnt=0;
clean(Fa,-1);clean(Len,0);
clean(Deep,0);
}
void Add(ll u,ll v,ll val){
Edge[Ecnt]=Node(v,val,Head[u]);
Head[u]=Ecnt++;
}
void DFS(ll u,ll fa){
for(ll i=Head[u];i+1;i=Edge[i].nxt){
ll temp=Edge[i].v;
if(temp==fa) continue;
if(Deep[temp]==0){
Deep[temp]=Deep[u]+1;
Fa[temp][0]=u;Len[temp][0]=Edge[i].val;
ll up=0,pre=u;
while(Fa[pre][up]>=0){
Fa[temp][up+1]=Fa[pre][up];
Len[temp][up+1]=Len[temp][up]+Len[pre][up];
pre=Fa[pre][up++];
}DFS(temp,u);
}
}
}
ll LCA(ll a,ll b){
ll ans=0;
if(Deep[a]<Deep[b]) swap(a,b);
ll lim=log2(1.0*Deep[a])+1;
for(ll i=lim;i>=0;--i){
if(Deep[Fa[a][i]]>=Deep[b]){
ans+=Len[a][i];
a=Fa[a][i];
}
}
// cout<<a<<" "<<b<<" "<<ans<<endl;
if(a==b) return a;
for(ll i=lim;i>=0;--i){
if(Fa[a][i]!=Fa[b][i]){
ans+=Len[a][i]+Len[b][i];
a=Fa[a][i];b=Fa[b][i];
}
}
if(Fa[a][0]==Fa[b][0]) return Fa[a][0];
return -1;
}
int Cmp(ll a,ll b){
return a>b;
}
void Solve(ll k,ll a,ll b){
ll rt=LCA(a,b);
// printf("rt=%lld\n",rt);
if(Deep[a]-Deep[rt]+Deep[b]-Deep[rt]+1<k){
printf("invalid request!\n"); return ;
}tot=0;
while(a!=rt){
Ans[++tot]=Delay[a];
a=Fa[a][0];
}
while(b!=rt){
Ans[++tot]=Delay[b];
b=Fa[b][0];
}Ans[++tot]=Delay[rt];
// printf("tot: %lld,",tot);
// for(int i=1;i<=tot;++i){
// printf("%lld ",Ans[i]);
// }printf("\n");
sort(Ans+1,Ans+tot+1,Cmp);
printf("%lld\n",Ans[k]);
}
int main(){
scanf("%lld%lld",&n,&m);Intt();
for(ll i=1;i<=n;++i){
scanf("%lld",&Delay[i]);
}
for(ll i=1;i<n;++i){
ll a,b;scanf("%lld%lld",&a,&b);
Add(a,b,1);Add(b,a,1);
}Deep[1]=1;DFS(1,-1);
while(m--){
ll k,a,b;scanf("%lld%lld%lld",&k,&a,&b);
if(k==0) Delay[a]=b;
else Solve(k,a,b);
}
}