[codeforces]Codeforces Global Round 1 F. Nearest Leaf
题解: 语文题???? 上面说的一段代码 告诉你的是 节点编号顺序与dfs序顺序一致 也就是你 dfs序以后编号就是[1,n] 根据这个特性 那么我们只需要维护每个叶子节点到查询v的距离即可 那么我们只需要离线所有查询 然后对子树修改即可 用线段树来维护区间加和区间最小值就行
#include <algorithm> #include <iostream> #include <cstring> #include <cstdio> #include <vector> #include <stack> #include <queue> #include <cmath> #include <set> #include <map> #define mp make_pair #define pb push_back #define pii pair<int,int> #define link(x) for(edge *j=h[x];j;j=j->next) #define inc(i,l,r) for(int i=l;i<=r;i++) #define dec(i,r,l) for(int i=r;i>=l;i--) const int MAXN=5e5+10; const double eps=1e-8; #define ll long long using namespace std; const ll inf=1e16; struct edge{int t;ll v;edge*next;}e[MAXN<<1],*h[MAXN],*o=e; void add(int x,int y,ll vul){o->t=y;o->v=vul;o->next=h[x];h[x]=o++;} ll read(){ ll 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 x*f; } int num[MAXN]; ll a[MAXN],sum[MAXN]; bool vis[MAXN]; void dfs(int x){ num[x]=1; link(x){ sum[j->t]=sum[x]+j->v; if(!vis[j->t])a[j->t]=sum[j->t]; else a[j->t]=inf; dfs(j->t); num[x]+=num[j->t]; } } ll minn[MAXN<<2],flag[MAXN<<2]; void push(int rt){ if(flag[rt]){ flag[rt<<1]+=flag[rt];flag[rt<<1|1]+=flag[rt]; minn[rt<<1]+=flag[rt];minn[rt<<1|1]+=flag[rt]; flag[rt]=0; } } void up(int rt){minn[rt]=min(minn[rt<<1],minn[rt<<1|1]);} void built(int rt,int l,int r){ if(l==r){minn[rt]=a[l];return ;} int mid=(l+r)>>1; built(rt<<1,l,mid); built(rt<<1|1,mid+1,r); up(rt); } void update(int rt,int l,int r,int ql,int qr,ll k){ if(ql>qr)return ; if(ql<=l&&r<=qr){minn[rt]+=k;flag[rt]+=k;return ;} int mid=(l+r)>>1; push(rt); if(ql<=mid)update(rt<<1,l,mid,ql,qr,k); if(qr>mid)update(rt<<1|1,mid+1,r,ql,qr,k); up(rt); } ll ans; void query(int rt,int l,int r,int ql,int qr){ if(ql<=l&&r<=qr){ans=min(ans,minn[rt]);return ;} int mid=(l+r)>>1; push(rt); if(ql<=mid)query(rt<<1,l,mid,ql,qr); if(qr>mid)query(rt<<1|1,mid+1,r,ql,qr); up(rt); } typedef struct node{ int l,r,id; }node; vector<node>vec[MAXN]; ll ans1[MAXN]; int n; void dfs2(int x){ for(int i=0;i<vec[x].size();i++){ ans=inf;query(1,1,n,vec[x][i].l,vec[x][i].r); ans1[vec[x][i].id]=ans; } link(x){ int t=j->t; update(1,1,n,t,t+num[t]-1,-(j->v)); update(1,1,n,1,t-1,j->v); update(1,1,n,t+num[t],n,j->v); dfs2(j->t); update(1,1,n,t,t+num[t]-1,j->v); update(1,1,n,1,t-1,-(j->v)); update(1,1,n,t+num[t],n,-(j->v)); } } int main(){ n=read();int q=read(); int u;ll k; inc(i,2,n)u=read(),k=read(),add(u,i,k),vis[u]=1; a[1]=inf;dfs(1); built(1,1,n); int v,l,r; inc(i,1,q)v=read(),l=read(),r=read(),vec[v].pb((node){l,r,i}); dfs2(1); inc(i,1,q)printf("%lld\n",ans1[i]); }