Zijian-lv #3 树句节狗提
Posted kong-ruo
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了Zijian-lv #3 树句节狗提相关的知识,希望对你有一定的参考价值。
如你所见,这是一道狗题
一棵树,多次询问与一个点距离至少为 $k$ 的点的权值和
$n,q leq 2525010$
sol:
长链剖分
需要注意的是这道题卡空间
我把我所有的 vector 换成链表才过了
#include <bits/stdc++.h> #define LL long long #define rep(i, s, t) for (register int i = (s), i##end = (t); i <= i##end; ++i) #define dwn(i, s, t) for (register int i = (s), i##end = (t); i >= i##end; --i) using namespace std; inline int read() { int x = 0, f = 1; char ch; for (ch = getchar(); !isdigit(ch); ch = getchar()) if (ch == ‘-‘) f = -f; for (; isdigit(ch); ch = getchar()) x = 10 * x + ch - ‘0‘; return x * f; } const int maxn = 2525015; int n, q, lim;/* vector<pair<int, int> > qs[maxn]; vector<int> G[maxn];*/ int qcd[maxn]; struct Chain { int head[maxn], nx[maxn], id[maxn], sz; Chain() {memset(head, 0, sizeof(head)); sz = 0;} inline void AddItem(int pos, int Item, int other = -1) { id[++sz] = Item; nx[sz] = head[pos]; head[pos] = sz; if(~other) qcd[sz] = other; } }qs, G; LL ans[maxn], pool[maxn], *f[maxn], *now=pool+1; int a[maxn]; void print(int q, LL* ans, int lim) { LL res; for(int i = 1; i <= q; ) { res = 0; for(int j = i; j <= min(q, i + lim - 1); j++) res ^= ans[j]; i += lim; printf("%lld ", res); } return ; } int mxs[maxn], mxd[maxn]; void dfs(int x) { mxd[x] = 0; for(int i=G.head[x];i;i=G.nx[i]) { dfs(G.id[i]); mxd[x] = max(mxd[x], mxd[G.id[i]] + 1); if((mxd[G.id[i]] > mxd[mxs[x]])) mxs[x] = G.id[i]; } } void solve(int x) { if(mxs[x]) { f[mxs[x]] = f[x] + 1; solve(mxs[x]); } f[x][0] = a[x]; for(int i=G.head[x];i;i=G.nx[i]) { if(G.id[i] == mxs[x]) continue; f[G.id[i]] = now; now += mxd[G.id[i]] + 1; solve(G.id[i]); rep(j, 0, mxd[G.id[i]]) f[x][j+1] += f[G.id[i]][j]; //cout << "to: " << to << " " << f[x][1] << endl; } //cout << x << " " << f[x][1] << endl; /*dwn(i, mxd[x]-1, 0) { cout << f[x][i] << " jiale " << f[x][i + 1] << endl; f[x][i] += f[x][i + 1]; }*/ f[x][0] += f[x][1]; for(int i=qs.head[x];i;i=qs.nx[i]) { if(qs.id[i] > mxd[x]) ans[qcd[i]] = 0; else ans[qcd[i]] = f[x][qs.id[i]]; }/* if(qs[x].size()) { // cout << "DEBUG: " << qs[x].first << " " << qs[x].second << " " << f[x][qs[x].first] << endl; // if(qs[x].first > mxd[x]) ans[qs[x].second] = 0; // else /*cout << "x: " << x << endl; rep(i, 0, mxd[x]) cout << f[x][i] << " "; cout << endl;*/ /* for(auto ii : qs[x]) { //cout << "DEBUG: " << ii.first << " " << mxd[x] << endl; if(ii.first > mxd[x]) ans[ii.second] = 0; else ans[ii.second] = f[x][ii.first]; } }*/ } int main() { n = read(); int x, y; rep(i, 1, n) a[i] = read(); rep(i, 2, n) { //x = read(), G[x].push_back(i); x = read(); G.AddItem(x, i); } q = read(); rep(i, 1, q) { x = read(); y = read(); //qs[x].push_back(make_pair(y, i)); qs.AddItem(x, y, i); } mxd[0] = -1; dfs(1); f[1] = now; now += mxd[1] + 1; solve(1); lim = read(); print(q, ans, lim); //rep(i, 1, q) cout << ans[i] << endl; }
论我的没 log 跑得没别人带 log 快
以上是关于Zijian-lv #3 树句节狗提的主要内容,如果未能解决你的问题,请参考以下文章