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
7
#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;
}

浙公网安备 33010602011771号