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

歡迎訪問(wèn) 生活随笔!

生活随笔

當(dāng)前位置: 首頁(yè) > 编程资源 > 编程问答 >内容正文

编程问答

【BZOJ 1036】[ZJOI2008]树的统计Count

發(fā)布時(shí)間:2025/4/9 编程问答 16 豆豆
生活随笔 收集整理的這篇文章主要介紹了 【BZOJ 1036】[ZJOI2008]树的统计Count 小編覺(jué)得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

【題目鏈接】:http://www.lydsy.com/JudgeOnline/problem.php?id=1036

【題意】

【題解】

樹(shù)鏈剖分入門(mén)題;
每一條鏈維護(hù)一個(gè)線段樹(shù)就好;
uppest數(shù)組維護(hù)這條鏈的最頂端的元素;
一條鏈一條鏈的往上走;直到兩個(gè)點(diǎn)在同一條鏈里面了
balabala

【完整代碼】

#include <bits/stdc++.h> using namespace std; #define lson l,m,rt<<1 #define rson m+1,r,rt<<1|1 #define LL long long #define rep1(i,a,b) for (int i = a;i <= b;i++) #define rep2(i,a,b) for (int i = a;i >= b;i--) #define mp make_pair #define pb push_back #define fi first #define se second #define rei(x) scanf("%d",&x) #define rel(x) scanf("%lld",&x) #define ref(x) scanf("%lf",&x)typedef pair<int, int> pii; typedef pair<LL, LL> pll;const int dx[9] = { 0,1,-1,0,0,-1,-1,1,1 }; const int dy[9] = { 0,0,0,-1,1,-1,1,-1,1 }; const double pi = acos(-1.0); const int N = 3e4+100; const int INF = 3e4 + 200;int n,fa[N],siz[N],dep[N],uppest[N],bh[N],cnt; int v[N],sum[N<<2],mx[N<<2]; vector <int> G[N];void in() {rei(n);rep1(i, 1, n - 1){int x, y;rei(x), rei(y);G[x].pb(y), G[y].pb(x);}rep1(i, 1, n)rei(v[i]); }void dfs1(int x) {int len = G[x].size();siz[x] = 1;rep1(i, 0, len - 1){int y = G[x][i];if (y == fa[x]) continue;fa[y] = x;dep[y] = dep[x] + 1;dfs1(y);siz[x] += siz[y];}}void dfs2(int x, int chain) {int len = G[x].size();int k = 0;bh[x] = ++cnt;uppest[x] = chain;rep1(i, 0, len - 1){int y = G[x][i];if (dep[y]>dep[x] && siz[y] > siz[k])k = y;}if (k == 0) return;dfs2(k, chain);rep1(i, 0, len - 1){int y = G[x][i];if (dep[y] > dep[x] && y != k)dfs2(y, y);} }void updata(int pos, int val,int l, int r, int rt) {if (l == r){sum[rt] = mx[rt] = val;return;}int m = (l + r) >> 1;if (pos <= m)updata(pos, val,lson);elseupdata(pos, val,rson);sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];mx[rt] = max(mx[rt << 1], mx[rt << 1 | 1]); }int query_max(int L, int R, int l, int r, int rt) {if (L <= l && r <= R)return mx[rt];int m = (l + r) >> 1;int temp1 = -INF;if (L <= m)temp1 = max(temp1, query_max(L, R, lson));if (m < R)temp1 = max(temp1, query_max(L, R, rson));return temp1; }int get_max(int u, int v) {int t = -3e4 - 100;while (uppest[u] != uppest[v]){if (dep[uppest[u]] < dep[uppest[v]])swap(u, v);t = max(t, query_max(bh[uppest[u]], bh[u], 1, n, 1));u = fa[uppest[u]];}if (dep[u] < dep[v])swap(u, v);t = max(t, query_max(bh[v], bh[u], 1, n, 1));return t; }int query_sum(int L, int R, int l, int r, int rt) {if (L <= l && r <= R)return sum[rt];int m = (l + r) >> 1;int temp = 0;if (L <= m)temp += query_sum(L, R, lson);if (m < R)temp += query_sum(L, R, rson);return temp; }int get_sum(int u, int v) {int t = 0;while (uppest[u] != uppest[v]){if (dep[uppest[u]] < dep[uppest[v]])swap(u, v);t += query_sum(bh[uppest[u]], bh[u], 1, n, 1);u = fa[uppest[u]];}if (dep[u] < dep[v])swap(u, v);t+=query_sum(bh[v], bh[u], 1, n, 1);return t; }void get_ans() {rep1(i, 1, n)updata(bh[i], v[i],1, n, 1);int q;rei(q);char s[8];rep1(i, 1, q){scanf("%s", s);if (s[0] == 'C'){int u, t;rei(u), rei(t);updata(bh[u], t, 1, n, 1);}else{int u, v;rei(u), rei(v);if (s[1] == 'M')printf("%d\n", get_max(u, v));elseprintf("%d\n", get_sum(u, v));}} }int main() {//freopen("F:\\rush.txt", "r", stdin);in();dfs1(1);dfs2(1, 1);get_ans();//printf("\n%.2lf sec \n", (double)clock() / CLOCKS_PER_SEC);return 0; }

轉(zhuǎn)載于:https://www.cnblogs.com/AWCXV/p/7626528.html

總結(jié)

以上是生活随笔為你收集整理的【BZOJ 1036】[ZJOI2008]树的统计Count的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。

如果覺(jué)得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。