日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

luogu P6329 【模板】点分树 | 震波

發布時間:2024/1/18 编程问答 28 豆豆
生活随笔 收集整理的這篇文章主要介紹了 luogu P6329 【模板】点分树 | 震波 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

https://www.luogu.com.cn/problem/P6329

先建一顆點分樹
考慮樹上的每個節點維護什么
因為樹高是log的,所以怎么暴力怎么維護就好了

維護兩個前綴和, u u u的子樹的點距離 u u u點的距離為 i i i的個數
以及對于 f a [ u ] fa[u] fa[u]
然后一路往上跳,每次加上fa[u]的減去u的即可
相當于市點分治的減去重復計算的部分
空間處理用vector即可
code:

#include<bits/stdc++.h> #define N 500050 using namespace std; struct edge {int v, nxt; } e[N << 1]; int p[N], eid; void init() {memset(p, - 1, sizeof p);eid = 0; } void insert(int u, int v) {e[eid].v = v;e[eid].nxt = p[u];p[u] = eid ++; } int dep[N], fa[N][20]; int LCA(int x, int y) {if(dep[x] < dep[y]) swap(x, y);for(int i = 18; i >= 0; i --) if(dep[fa[x][i]] >= dep[y]) x = fa[x][i];if(x == y) return x;for(int i = 18; i >= 0; i --) if(fa[x][i] != fa[y][i]) x = fa[x][i], y = fa[y][i];return fa[x][0]; } int dis(int x, int y) {return dep[x] + dep[y] - 2 * dep[LCA(x, y)]; } void dfsp(int u) {dep[u] = dep[fa[u][0]] + 1;for(int i = p[u]; i + 1; i = e[i].nxt) {int v = e[i].v;if(v == fa[u][0]) continue;fa[v][0] = u; dfsp(v);} } vector<int> t[2][N]; int size[N], msize[N], vis[N], FA[N]; int sz, mx, rt; void dfs(int u, int ff) {size[u] = 1; msize[u] = 0;for(int i = p[u]; i + 1; i = e[i].nxt) {int v = e[i].v;if(v == ff || vis[v]) continue;dfs(v, u); size[u] += size[v];msize[u] = max(msize[u], size[v]);}msize[u] = max(msize[u], sz - size[u]);if(msize[u] < mx) mx = msize[u], rt = u; } void solve(int u, int ff, int n) {mx = sz = n, rt = 0;dfs(u, u); u = rt;FA[u] = ff; size[u] = sz;t[0][u].resize(sz + 5), t[1][u].resize(sz + 5);vis[u] = 1;for(int i = p[u]; i + 1; i = e[i].nxt) {int v = e[i].v;if(vis[v]) continue;solve(v, u, size[v]);} } #define lowbit(x) (x & -x) void update(int o, int u, int x, int y) { ++ x;for(; x <= size[u] + 1; x += lowbit(x)) t[o][u][x] += y; } int query(int o, int u, int x) { x = min(x + 1, size[u] + 1);int ret = 0;for(; x; x -= lowbit(x)) ret += t[o][u][x];return ret; } void Add(int x, int y) {for(int i = x; i; i = FA[i]) update(0, i, dis(i, x), y);for(int i = x; FA[i]; i = FA[i]) update(1, i, dis(FA[i], x), y); } int n, m, val[N]; int main() {init();scanf("%d%d", &n, &m);for(int i = 1; i <= n; i ++) scanf("%d", &val[i]);for(int i = 1; i < n; i ++) {int u, v;scanf("%d%d", &u, &v);insert(u, v), insert(v, u);}dfsp(1);for(int j = 1; j <= 18; j ++)for(int i = 1; i <= n; i ++) fa[i][j] = fa[fa[i][j - 1]][j - 1];solve(1, 0, n);for(int i = 1; i <= n; i ++) Add(i, val[i]);int lst = 0;while(m --) {int o, x, y;scanf("%d%d%d", &o, &x, &y);x ^= lst, y ^= lst;if(!o) {lst = query(0, x, y);for(int i = x; FA[i]; i = FA[i]) {int d = dis(x, FA[i]);if(d <= y) lst += query(0, FA[i], y - d) - query(1, i, y - d);} printf("%d\n", lst);} else Add(x, y - val[x]), val[x] = y;}return 0; }

總結

以上是生活随笔為你收集整理的luogu P6329 【模板】点分树 | 震波的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。