CF - 1110F Nearest Leaf
阿新 • • 發佈:2019-02-09
lan none spa urn 區間 分享圖片 bits 技術 pen
題目傳送門
題解:
先用題目給定的dfs方式得到dfs序,記錄下出入的dfs序。
很明顯可以得知的是,以u為根的子樹的dfs序在 in[u] - out[u] 的範圍之內。
將每個詢問先全部存到對應的節點上。
然後我們以1為root,先求出每個葉子節點到1的距離。
對1的詢問查詢更新完答案之後。
(假設1和2之間有一條權值為w的邊)
那麽以2為根的話,就相當於是 in[2] --- out[2] 區間裏面的所有值的距離 -= w, 其他點的距離 += w。
然後對於每個點都這樣處理。
註意修改和還原更新。
代碼:
/* code by: zstu wxk time: 2019/02/09 */ #includeView Code<bits/stdc++.h> using namespace std; #define Fopen freopen("_in.txt","r",stdin); freopen("_out.txt","w",stdout); #define LL long long #define ULL unsigned LL #define fi first #define se second #define pb push_back #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define lch(x) tr[x].son[0] #definerch(x) tr[x].son[1] #define max3(a,b,c) max(a,max(b,c)) #define min3(a,b,c) min(a,min(b,c)) typedef pair<int,int> pll; const int inf = 0x3f3f3f3f; const int _inf = 0xc0c0c0c0; const LL INF = 0x3f3f3f3f3f3f3f3f; const LL _INF = 0xc0c0c0c0c0c0c0c0; const LL mod = (int)1e9+7; const int N = 5e5 + 100; vector<pll> vc[N];int in[N], out[N], tot; LL a[N]; int n, q; void dfs(int u, LL ct){ in[u] = ++tot; if(vc[u].size()) a[tot] = INF; else a[tot] = ct; for(pll p : vc[u]){ dfs(p.fi, ct+p.se); } out[u] = tot; } LL Mn[N<<2], lz[N<<2]; void PushUp(int rt){ Mn[rt] = min(Mn[rt<<1], Mn[rt<<1|1]); } void PushDown(int rt){ if(lz[rt]){ lz[rt<<1] += lz[rt]; lz[rt<<1|1] += lz[rt]; Mn[rt<<1] += lz[rt]; Mn[rt<<1|1] += lz[rt]; lz[rt] = 0; } return ; } void Build(int l, int r, int rt){ if(l == r){ Mn[rt] = a[l]; return ; } int m = l+r >> 1; Build(lson); Build(rson); PushUp(rt); return ; } void Updata(int L, int R, LL C, int l, int r, int rt){ if(L <= l && r <= R){ lz[rt] += C; Mn[rt] += C; return ; } PushDown(rt); int m = l+r >> 1; if(L <= m) Updata(L, R, C, lson); if(m < R) Updata(L, R, C, rson); PushUp(rt); return ; } LL Query(int L, int R, int l, int r, int rt){ if(L <= l && r <= R){ return Mn[rt]; } PushDown(rt); int m = l+r >> 1; LL ret = INF; if(L <= m) ret = Query(L, R, lson); if(m < R) ret = min(ret, Query(L, R, rson)); return ret; } #define mp make_pair vector<pair<pll,int>> Q[N]; LL ans[N]; void Dfs(int u, int ct){ Updata(1, n, ct, 1, n, 1); Updata(in[u], out[u], -2*ct, 1, n, 1); for(auto x : Q[u]){ ans[x.se] = Query(x.fi.fi, x.fi.se, 1, n, 1); } for(pll x : vc[u]){ Dfs(x.fi, x.se); } Updata(1, n, -ct, 1, n, 1); Updata(in[u], out[u], 2*ct, 1, n, 1); return ; } void Ac(){ for(int i = 2, v, w; i <= n; ++i){ scanf("%d%d", &v, &w); vc[v].pb({i,w}); } dfs(1, 0); Build(1, n, 1); for(int i = 1,u,l,r; i <= q; ++i){ scanf("%d%d%d", &u, &l, &r); Q[u].pb(mp(mp(l,r),i)); } Dfs(1, 0); for(int i = 1; i <= q; ++i) printf("%I64d\n", ans[i]); } int main(){ while(~scanf("%d%d", &n, &q)){ Ac(); } return 0; }
CF - 1110F Nearest Leaf