题目大意:
n个城市构成一个树 m支军队 每只军队守卫 在xi到yi的最短路径上的城市
q个重要人物从vi出发 找到离根最近的点使从vi到这个点上所有路径都可以被至少ki个军队完全覆盖
输出每个答案的点的深度
思路:
对于每个军队 可以拆成两个链
在深度较大的节点的权值线段树上把深度较低的点+1
然后合并线段树
查询的时候查询子树线段树中第k小的
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include<iostream> 2 #include<cstdio> 3 #include<cmath> 4 #include<cstdlib> 5 #include<cstring> 6 #include<algorithm> 7 #include<vector> 8 #include<queue> 9 #include<map> 10 #define inf 2139062143 11 #define ll long long 12 #define MAXN 200100 13 using namespace std; 14 inline int read() 15 { 16 int x=0,f=1;char ch=getchar(); 17 while(!isdigit(ch)) {if(ch=='-') f=-1;ch=getchar();} 18 while(isdigit(ch)) {x=x*10+ch-'0';ch=getchar();} 19 return x*f; 20 } 21 int n,m,f[MAXN][18],dep[MAXN],hsh[MAXN],sz[MAXN],val[MAXN<<6]; 22 int nxt[MAXN<<1],fst[MAXN],to[MAXN<<1],cnt,rt[MAXN],ls[MAXN<<6],rs[MAXN<<6]; 23 void add(int u,int v) {nxt[++cnt]=fst[u],fst[u]=cnt,to[cnt]=v;} 24 void dfs(int x) 25 { 26 hsh[x]=++cnt,sz[x]=1; 27 for(int i=1;(1<<i)<=dep[x];i++) f[x][i]=f[f[x][i-1]][i-1]; 28 for(int i=fst[x];i;i=nxt[i]) 29 if(to[i]!=f[x][0]){dep[to[i]]=dep[x]+1,f[to[i]][0]=x;dfs(to[i]);sz[x]+=sz[to[i]];} 30 } 31 int lca(int u,int v) 32 { 33 if(dep[u]<dep[v]) swap(u,v); 34 int t=dep[u]-dep[v]; 35 for(int i=0;i<=17;i++) 36 if((1<<i)&t) u=f[u][i]; 37 if(u==v) return u; 38 for(int i=17;i>=0;i--) 39 if(f[u][i]!=f[v][i]) u=f[u][i],v=f[v][i]; 40 return f[u][0]; 41 } 42 void inst(int &k,int l,int r,int x) 43 { 44 if(!k) k=++cnt; 45 val[k]++; 46 if(l==r) return ; 47 int mid=(l+r)>>1; 48 if(x<=mid) inst(ls[k],l,mid,x); 49 else inst(rs[k],mid+1,r,x); 50 } 51 void merge(int &a,int b) 52 { 53 if(!a) {a=b;return ;} 54 if(!b) return ; 55 val[a]+=val[b]; 56 merge(ls[a],ls[b]); 57 merge(rs[a],rs[b]); 58 } 59 int query(int k1,int k2,int l,int r,int a,int b) 60 { 61 if(!k1) return 0; 62 if(l==a&&r==b) return val[k1]-val[k2]; 63 int mid=(l+r)>>1; 64 if(b<=mid) return query(ls[k1],ls[k2],l,mid,a,b); 65 else if(a>mid) return query(rs[k1],rs[k2],mid+1,r,a,b); 66 else return query(ls[k1],ls[k2],l,mid,a,mid)+query(rs[k1],rs[k2],mid+1,r,mid+1,b); 67 } 68 int ans(int k1,int k2,int l,int r,int x) 69 { 70 //cout<<l<<" "<<r<<" "<<val[k1]-val[k2]<<" "<<x<<endl; 71 if(l==r) return l; 72 int mid=(l+r)>>1; 73 if(x<=val[ls[k1]]-val[ls[k2]]) return ans(ls[k1],ls[k2],l,mid,x); 74 else return ans(rs[k1],rs[k2],mid+1,r,x-val[ls[k1]]+val[ls[k2]]); 75 } 76 int main() 77 { 78 n=read(),m=read();int a,b,c; 79 for(int i=1;i<n;i++) {a=read(),b=read();add(a,b);add(b,a);} 80 cnt=0;dfs(1);cnt=0; 81 while(m--) 82 { 83 a=read(),b=read(),c=lca(a,b); 84 inst(rt[hsh[a]],1,n,dep[c]+1); 85 inst(rt[hsh[b]],1,n,dep[c]+1); 86 } 87 for(int i=1;i<=n;i++) merge(rt[i],rt[i-1]); 88 m=read(); 89 while(m--) 90 { 91 a=read(),b=read(); 92 //cout<<query(rt[hsh[a]+sz[a]-1],rt[hsh[a]-1],1,n,1,dep[a]+1)<<endl; 93 if(query(rt[hsh[a]+sz[a]-1],rt[hsh[a]-1],1,n,1,dep[a]+1)<b) puts("0"); 94 else printf("%d ",dep[a]+1-ans(rt[hsh[a]+sz[a]-1],rt[hsh[a]-1],1,n,b)); 95 } 96 }