1. 程式人生 > >[codeforces]Codeforces Global Round 1 F. Nearest Leaf

[codeforces]Codeforces Global Round 1 F. Nearest Leaf

只需要 \n git inf next leaf col mes 一段

題解: 語文題???? 上面說的一段代碼 告訴你的是 節點編號順序與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]);
}

  

[codeforces]Codeforces Global Round 1 F. Nearest Leaf