Given a tree, the tree has \ (P \) paths, respectively, the right value \ (C_i \) . Given \ (q \) th inquiry, asking each given a path, ask all the sub-path is a tree path of inquiry path, the weight of the \ (k \) small is. \ (n \ leq 40000 \)
Solution
Consider a given path \ ((a, b) \ ) is the interrogation path \ ((u, v) \ ) condition of the sub-path, may wish to set \ (a, u \) are each smaller sequence that DFS
- If \ ((a, b) \ ) is a straight-chain, then the \ (dfn [u] \ notin [dfn [x], fin [x]], dfn [v] \ in [dfn [b], fin [b ]] \) , where \ (X \) is the \ (a \) to \ (B \) take the first point encountered, this can be determined using a multiplier
- If \ ((a, b) \ ) is bent chain, then \ (dfn [u] \ in [dfn [a], fin [a]], dfn [v] \ in [dfn [b], fin [b ]] \)
So the question into a number of rectangular two-dimensional plane, given \ (q \) a point to ask, ask each rectangle covering all points in this section \ (k \) rectangular weight is much smaller weights
If this is not the first \ (k \) requirements, direct scanning line, segment tree maintenance can be
Now more \ (K \) requirement, then segment tree to tree cover segment, to maintain the outer subscript inner maintain weight
#include <bits/stdc++.h>
using namespace std;
const int N = 200005;
const int M = 2e7;
const int lim = 1e9;
int n,p,q,a[N],b[N],c[N],u[N],v[N],k[N],fa[N][19],dep[N],t1,t2,t3;
int dfn[N],fin[N],ind,nrect,ans[N];
vector <int> g[N];
struct point {
int x,y,k;
} pt[N];
struct rect {
int x1,y1,x2,y2,v;
} rec[N];
struct query {
int x,t,k,id;
};
struct event {
int l,r,t,v;
};
vector <query> que[N];
vector <event> evp[N],evn[N];
void dfs(int p) {
dfn[p]=++ind;
for(int i=1;i<19;i++) fa[p][i]=fa[fa[p][i-1]][i-1];
for(int q:g[p]) if(dfn[q]==0) dep[q]=dep[p]+1, fa[q][0]=p, dfs(q);
fin[p]=ind;
}
int getpoint(int p,int q) {
if(dep[p]<dep[q]) swap(p,q);
for(int i=18;i>=0;--i) if(dep[fa[p][i]]>dep[q]) p=fa[p][i];
return p;
}
namespace iseg {
int ch[M][2],a[M],ind;
void modify(int p,int l,int r,int pos,int val) {
a[p]+=val;
if(l<r) {
if(pos<=(l+r)/2) {
if(ch[p][0]==0) ch[p][0]=++ind;
modify(ch[p][0],l,(l+r)/2,pos,val);
}
else {
if(ch[p][1]==0) ch[p][1]=++ind;
modify(ch[p][1],(l+r)/2+1,r,pos,val);
}
}
}
int newnode() {
return ++ind;
}
int query(int p,int l,int r,int ql,int qr) {
if(l>qr || r<ql || p==0) return 0;
if(l>=ql&&r<=qr) return a[p];
return query(ch[p][0],l,(l+r)/2,ql,qr)+query(ch[p][1],(l+r)/2+1,r,ql,qr);
}
}
namespace oseg {
int a[M];
void modify(int p,int l,int r,int ql,int qr,int pos,int val) {
if(l>qr || r<ql) return;
if(l>=ql&&r<=qr) {
if(a[p]==0) a[p]=iseg::newnode();
iseg::modify(a[p],1,lim,pos,val);
}
else {
modify(p*2,l,(l+r)/2,ql,qr,pos,val);
modify(p*2+1,(l+r)/2+1,r,ql,qr,pos,val);
}
}
int query(int p,int l,int r,int x,int vl,int vr) {
int tmp = iseg::query(a[p],1,lim,vl,vr);
if(l==r) {
return tmp;
}
else {
if(x<=(l+r)/2) return tmp + query(p*2,l,(l+r)/2,x,vl,vr);
else return tmp + query(p*2+1,(l+r)/2+1,r,x,vl,vr);
}
}
}
namespace seq {
vector <int> a[N];
void modify(int ql,int qr,int pos) {
oseg::modify(1,1,n,ql,qr,pos,1);
}
void erase(int ql,int qr,int pos) {
oseg::modify(1,1,n,ql,qr,pos,-1);
}
int query(int x,int vl,int vr) {
return oseg::query(1,1,n,x,vl,vr);
}
int kth(int x,int k) {
int l=0,r=1e9;
while(l<r) {
int mid=(l+r)/2;
if(query(x,1,mid)>=k) r=mid;
else l=mid+1;
}
return l;
}
}
void read() {
ios::sync_with_stdio(false);
cin>>n>>p>>q;
for(int i=1;i<n;i++) {
cin>>t1>>t2;
g[t1].push_back(t2);
g[t2].push_back(t1);
}
for(int i=1;i<=p;i++) {
cin>>a[i]>>b[i]>>c[i];
}
for(int i=1;i<=q;i++) {
cin>>u[i]>>v[i]>>k[i];
}
dfs(1);
}
void make() {
for(int i=1;i<=p;i++) {
if(dfn[a[i]]>dfn[b[i]]) swap(a[i],b[i]);
if(dfn[a[i]]<=dfn[b[i]] && fin[a[i]]>=dfn[b[i]]) {
a[i]=getpoint(a[i],b[i]);
rec[++nrect]={1,dfn[b[i]],dfn[a[i]]-1,fin[b[i]],c[i]};
rec[++nrect]={fin[a[i]]+1,dfn[b[i]],n,fin[b[i]],c[i]};
}
else {
rec[++nrect]={dfn[a[i]],dfn[b[i]],fin[a[i]],fin[b[i]],c[i]};
}
}
for(int i=1;i<=q;i++) {
if(dfn[u[i]]>dfn[v[i]]) swap(u[i],v[i]);
pt[i]={dfn[u[i]],dfn[v[i]],k[i]};
}
for(int i=1;i<=nrect;i++) {
if(rec[i].x1>rec[i].x2 || rec[i].y1>rec[i].y2) continue;
evp[rec[i].y1].push_back({rec[i].x1,rec[i].x2,rec[i].y1,rec[i].v});
evn[rec[i].y2].push_back({rec[i].x1,rec[i].x2,rec[i].y2,rec[i].v});
evp[rec[i].x1].push_back({rec[i].y1,rec[i].y2,rec[i].x1,rec[i].v});
evn[rec[i].x2].push_back({rec[i].y1,rec[i].y2,rec[i].x2,rec[i].v});
}
for(int i=1;i<=q;i++) {
que[pt[i].y].push_back({pt[i].x,pt[i].y,pt[i].k,i});
}
}
void solve() {
for(int i=1;i<=n;i++) {
for(event e:evp[i]) {
seq::modify(e.l,e.r,e.v);
}
for(query q:que[i]) {
ans[q.id]=seq::kth(q.x,q.k);
}
for(event e:evn[i]) {
seq::erase(e.l,e.r,e.v);
}
}
}
void print() {
for(int i=1;i<=q;i++) cout<<ans[i]<<endl;
}
signed main() {
read();
make();
solve();
print();
}