日韩av黄I国产麻豆传媒I国产91av视频在线观看I日韩一区二区三区在线看I美女国产在线I麻豆视频国产在线观看I成人黄色短片

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 >

HDU 3966-Aragorn's Story 树链剖分+树状数组

發(fā)布時(shí)間:2023/12/13 41 豆豆
生活随笔 收集整理的這篇文章主要介紹了 HDU 3966-Aragorn's Story 树链剖分+树状数组 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

題目鏈接


題意:有一棵樹,每個(gè)節(jié)點(diǎn)有權(quán)值
有三種操作:

  • I c1 c2 k 從節(jié)點(diǎn)c1到節(jié)點(diǎn)c2的路徑上每個(gè)節(jié)點(diǎn)權(quán)值增加k
  • D c1 c2 k 從節(jié)點(diǎn)c1到節(jié)點(diǎn)c2的路徑上每個(gè)節(jié)點(diǎn)權(quán)值減少k
  • Q i 查詢節(jié)點(diǎn)i的權(quán)值是多少

思路:

  • 樹鏈剖分處理出來的鏈放在數(shù)組中,使用樹狀數(shù)組維護(hù)
  • 樹狀數(shù)組進(jìn)行區(qū)間修改,單點(diǎn)查詢

樹狀數(shù)組區(qū)間修改,單點(diǎn)查詢的方法:鏈接


#include <stdio.h> #include <iostream> #include <string.h> #include <stdlib.h> #include <vector> #include <algorithm> #include <queue> #include <map> #include <stack> #include <string> #include <math.h> #include <bitset> #include <ctype.h> #define CLR(n,b) memset(n, b, sizeof(n)) using namespace std; typedef pair<int,int> P; typedef long long LL; const int INF = 0x3f3f3f3f; const double PI = acos(-1.0); const double eps = 1e-9; const int N = 6e4 + 5; const int mod = 1e9 + 7; struct Edge {int u,v;Edge() {}Edge(int a, int b): u(a), v(b) {} }; int fa[N],son[N], p[N],fp[N], top[N],dep[N],sz[N]; int pos; int n,m,k; vector<Edge> edges; vector<int> G[N]; void init(int n) {CLR(fa, 0); CLR(son, -1); CLR(p, -1);CLR(fp, -1); CLR(top, 0); CLR(sz, 0); CLR(dep, 0);pos = 0; edges.clear();for(int i = 0; i <= n; i++) G[i].clear(); } void addedge(int u, int v) {edges.push_back(Edge(u,v));edges.push_back(Edge(v,u));int m = edges.size();G[u].push_back(m-2);G[v].push_back(m-1); }// 樹鏈剖分void dfs(int u, int pre, int d) {fa[u] = pre;dep[u] = d;sz[u] = 1;son[u] = -1;for(int i = 0; i < G[u].size(); i++){Edge &e = edges[G[u][i]];int v = e.v;if(v == pre) continue;dfs(v, u, d+1);sz[u] += sz[v];if(son[u] == -1 || sz[son[u]] < sz[v])son[u] = v;} }void getpos(int u, int sp) {top[u] = sp;p[u] = ++pos;fp[p[u]] = u;if(son[u] == -1) return;getpos(son[u], sp);for(int i = 0; i < G[u].size(); i++){Edge &e = edges[G[u][i]];int v = e.v;if(v == son[u] || v == fa[u]) continue;getpos(v, v);} }// 樹狀數(shù)組 int c[N]; inline int lowbit(int x) {return x&(-x); } void add(int x, int val) {while(x <= n){c[x] += val;x += lowbit(x);} } int sum(int x) {int ans = 0;while(x){ans += c[x];x -= lowbit(x);}return ans; }// change void change(int x, int y, int val) {int u = x, v = y;int f1 = top[u], f2 = top[v];while(f1 != f2){if(dep[f1] < dep[f2]){swap(f1,f2);swap(u,v);}add(p[f1], val);add(p[u]+1, -val);u = fa[f1];f1 =top[u];}if(dep[u] > dep[v]) swap(u,v);add(p[u], val);add(p[v]+1, -val); }int a[N]; int main() {while(~scanf("%d%d%d", &n, &m, &k)){init(n);for(int i = 1; i <= n; i++){scanf("%d", &a[i]);}for(int i = 0; i < m; i++){int u,v;scanf("%d%d", &u, &v);addedge(u,v);}dfs(1,1,0);getpos(1,1);memset(c, 0, sizeof(c));for(int i = 1; i <= n; i++){add(p[i], a[i]);add(p[i]+1, -a[i]);}while(k--){char cmd[10];int x,y,z;scanf("%s", cmd);if(cmd[0] == 'Q'){scanf("%d", &x);printf("%d\n", sum(p[x]));}else{scanf("%d%d%d", &x,&y,&z);if(cmd[0] == 'D')z = -z;change(x,y,z);}}}return 0; }

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

總結(jié)

以上是生活随笔為你收集整理的HDU 3966-Aragorn's Story 树链剖分+树状数组的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

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