题意
给出一棵树,每次询问一个点$x$
到编号在$[l,r]$中的点的距离的最小值。
$n,qle 10^5$
大概是最简单的动态点分治了,注意开大数组即可,如果改成求最大值这道题会有意思很多
代码:
1 #include<iostream> 2 #include<cstdio> 3 #include<cstring> 4 #define M 100010 5 #define ls ch[node][0] 6 #define rs ch[node][1] 7 using namespace std; 8 int n,m,num,cnt,root,S; 9 int head[M],son[M],sz[M],top[M],deep[M],fa[M],f[M],size[M],maxn[M],dis[M],rt[M]; 10 int val[M<<7],ch[M<<7][2];bool vis[M]; 11 struct point{int to,next,dis;}e[M<<1]; 12 void add(int from,int to,int dis) { 13 e[++num].next=head[from]; 14 e[num].to=to; 15 e[num].dis=dis; 16 head[from]=num; 17 } 18 void dfs1(int x) { 19 sz[x]=1;deep[x]=deep[fa[x]]+1; 20 for(int i=head[x];i;i=e[i].next) { 21 int to=e[i].to; 22 if(to==fa[x]) continue; 23 fa[to]=x,dis[to]=dis[x]+e[i].dis; 24 dfs1(to),sz[x]+=sz[to]; 25 if(sz[son[x]]<sz[to]) son[x]=to; 26 } 27 } 28 void dfs2(int x,int tp) { 29 top[x]=tp; 30 if(son[x]) dfs2(son[x],tp); 31 for(int i=head[x];i;i=e[i].next) 32 if(e[i].to!=fa[x]&&e[i].to!=son[x]) 33 dfs2(e[i].to,e[i].to); 34 } 35 int lca(int x,int y) { 36 while(top[x]!=top[y]) { 37 if(deep[top[x]]<deep[top[y]]) swap(x,y); 38 x=fa[top[x]]; 39 } 40 return deep[x]<deep[y]?x:y; 41 } 42 int getdis(int x,int y) { 43 return dis[x]+dis[y]-2*dis[lca(x,y)]; 44 } 45 void getroot(int x,int fa) { 46 size[x]=1;maxn[x]=0; 47 for(int i=head[x];i;i=e[i].next) { 48 int to=e[i].to; 49 if(to==fa||vis[to]) continue; 50 getroot(to,x),size[x]+=size[to]; 51 maxn[x]=max(maxn[x],size[to]); 52 } 53 maxn[x]=max(maxn[x],S-size[x]); 54 if(maxn[x]<maxn[root]) root=x; 55 } 56 void solve(int x,int ff) { 57 vis[x]=true,f[x]=ff; 58 for(int i=head[x];i;i=e[i].next) { 59 int to=e[i].to; 60 if(vis[to]) continue; 61 S=size[to],root=0,getroot(to,0); 62 solve(root,x); 63 } 64 } 65 void update(int node) { 66 if(ls) val[node]=min(val[node],val[ls]); 67 if(rs) val[node]=min(val[node],val[rs]); 68 } 69 void insert(int &node,int l,int r,int x,int v) { 70 if(!node) node=++cnt,val[node]=1e9; 71 if(l==r) { 72 val[node]=v;return; 73 } 74 int mid=(l+r)/2; 75 if(x<=mid) insert(ls,l,mid,x,v); 76 else insert(rs,mid+1,r,x,v); 77 update(node); 78 } 79 int query(int node,int l,int r,int l1,int r1) { 80 if(!node) return 1e9; 81 if(l1<=l&&r1>=r) return val[node]; 82 int mid=(l+r)/2,ans=1e9; 83 if(l1<=mid) ans=min(ans,query(ls,l,mid,l1,r1)); 84 if(r1>mid) ans=min(ans,query(rs,mid+1,r,l1,r1)); 85 return ans; 86 } 87 void pushin(int x) { 88 for(int i=x;i;i=f[i]) 89 insert(rt[i],1,n,x,getdis(x,i)); 90 } 91 int ask(int x,int l,int r) { 92 int ans=1e9; 93 for(int i=x;i;i=f[i]) 94 ans=min(ans,getdis(x,i)+query(rt[i],1,n,l,r)); 95 return ans; 96 } 97 int main() { 98 scanf("%d",&n); 99 for(int i=1;i<n;i++) { 100 int x,y,z;scanf("%d%d%d",&x,&y,&z); 101 add(x,y,z),add(y,x,z); 102 } 103 dfs1(1),dfs2(1,1); 104 S=maxn[0]=n,getroot(1,0),solve(root,0); 105 for(int i=1;i<=n;i++) pushin(i); 106 scanf("%d",&m); 107 for(int i=1;i<=m;i++) { 108 int l,r,x;scanf("%d%d%d",&l,&r,&x); 109 printf("%d ",ask(x,l,r)); 110 } 111 return 0; 112 }