spoj COT - Count on a tree

COT - Count on a tree

 

You are given a tree with N nodes. The tree nodes are numbered from 1 to N. Each node has an integer weight.

We will ask you to perform the following operation:

  • u v k : ask for the kth minimum weight on the path from node u to node v

Input

In the first line there are two integers N and M. (N, M <= 100000)

In the second line there are N integers. The ith integer denotes the weight of the ith node.

In the next N-1 lines, each line contains two integers u v, which describes an edge (u, v).

In the next M lines, each line contains three integers u v k, which means an operation asking for the kth minimum weight on the path from node u to node v.

Output

For each operation, print its result.

Example

Input:
8 5
105 2 9 3 8 5 7 7
1 2
1 3
1 4
3 5
3 6
3 7
4 8
2 5 1
2 5 2
2 5 3
2 5 4
7 8 2 
Output:
2
8
9
105
#include <bits/stdc++.h>
#define ll long long
const int MAXN=1e5+10;
using namespace std;
ll readll(){
    ll x=0,f=1;char ch=getchar();
    while(ch<'0'||ch>'9'){if(ch=='-')f=-1;ch=getchar();}
    while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();}
    return x*f;
}
int readint(){
    int x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}
typedef struct node{
    int l,r,ans;
}node;
node d[MAXN*25];
int cnt,rt[MAXN],p[MAXN],n,a[MAXN],q,cnt2;
vector<int>vec[MAXN];
vector<int>vv;
void update(int &x,int y,int l,int r,int vul){
    x=++cnt;d[x]=d[y];d[x].ans++;
    if(l==r) return ;
    int mid=(l+r)>>1;
    if(vul<=mid) update(d[x].l,d[y].l,l,mid,vul);
    else update(d[x].r,d[y].r,mid+1,r,vul);
}
void querty(int x,int y,int z,int l,int r,int &ans,int k,int lCa){
    if(l==r){
        ans=l;return ;
    }
    int mid=(l+r)>>1;
    int t=d[d[x].l].ans+d[d[y].l].ans-2*d[d[z].l].ans+(l<=lCa&&lCa<=mid);
    if(k<=t) querty(d[x].l,d[y].l,d[z].l,l,mid,ans,k,lCa);
    else querty(d[x].r,d[y].r,d[z].r,mid+1,r,ans,k-t,lCa);
}
int b[MAXN<<1],c[MAXN<<1],cnt1,first[MAXN],dp[MAXN<<1][21],pos[MAXN<<1][21],mu[21],mn[MAXN<<1];
void pre_rmq(){
    int t=(n<<1);mn[0]=-1;
    for(int i=1;i<=t;i++)  mn[i]=((i&(i-1))==0)? mn[i-1]+1 : mn[i-1];
    for(int i=1;i<=t;i++) dp[i][0]=c[i],pos[i][0]=i;
    for(int i=1;i<=20;i++){
        for(int j=1;j+mu[i]-1<=t;j++){
            if(dp[j][i-1]<=dp[j+mu[i-1]][i-1]) dp[j][i]=dp[j][i-1],pos[j][i]=pos[j][i-1];
            else dp[j][i]=dp[j+mu[i-1]][i-1],pos[j][i]=pos[j+mu[i-1]][i-1];
        }
    }
}
int rmq(int l,int r){
    int k=mn[r-l+1];
    int t1=dp[l][k];int t2=dp[r-mu[k]+1][k];
    if(t1<=t2) return b[pos[l][k]];
    else return b[pos[r-mu[k]+1][k]];
}
void dfs(int v,int pre,int dep){
    b[++cnt1]=v;c[cnt1]=dep+1;first[v]=cnt1;
    cnt++;p[v]=++cnt2;update(rt[cnt2],rt[p[pre]],1,n,a[v]);
    for(int i=0;i<vec[v].size();i++){
        int u=vec[v][i];
        if(u!=pre){
            dfs(u,v,dep+1);
            b[++cnt1]=v;c[cnt1]=dep+1;
        }
    }
}
int main(){
    mu[0]=1;
    for(int i=1;i<=20;i++) mu[i]=(mu[i-1]<<1);
    n=readint();q=readint();int u,v,k,u1,v1,Lca,ans;
    for(int i=1;i<=n;i++) a[i]=readint(),vv.push_back(a[i]);
    for(int i=1;i<n;i++){
        u=readint();v=readint();vec[u].push_back(v);
        vec[v].push_back(u);
    }
    sort(vv.begin(),vv.end());
    int size=unique(vv.begin(),vv.end())-vv.begin();
    for(int i=1;i<=n;i++) a[i]=lower_bound(vv.begin(),vv.begin()+size,a[i])-vv.begin()+1;
    dfs(1,0,0);
    pre_rmq();
    while(q--){
        u=readint();v=readint();k=readint();u1=p[u];v1=p[v];Lca=rmq(min(first[u],first[v]),max(first[u],first[v]));
        querty(rt[u1],rt[v1],rt[p[Lca]],1,n,ans,k,a[Lca]);
        printf("%d\n",vv[ans-1]);
    }
    return 0;
}

  

posted @ 2018-03-28 20:15  wang9897  阅读(281)  评论(0编辑  收藏  举报