HDU 3966-Aragorn's Story 树链剖分+树状数组
生活随笔
收集整理的這篇文章主要介紹了
HDU 3966-Aragorn's Story 树链剖分+树状数组
小編覺得挺不錯的,現(xiàn)在分享給大家,幫大家做個參考.
題目鏈接
題意:有一棵樹,每個節(jié)點有權(quán)值
有三種操作:
- I c1 c2 k 從節(jié)點c1到節(jié)點c2的路徑上每個節(jié)點權(quán)值增加k
- D c1 c2 k 從節(jié)點c1到節(jié)點c2的路徑上每個節(jié)點權(quán)值減少k
- Q i 查詢節(jié)點i的權(quán)值是多少
思路:
- 樹鏈剖分處理出來的鏈放在數(shù)組中,使用樹狀數(shù)組維護
- 樹狀數(shù)組進行區(qū)間修改,單點查詢
樹狀數(shù)組區(qū)間修改,單點查詢的方法:鏈接
#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)容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: [IoC容器Unity]第三回:依赖注入
- 下一篇: 建站手册-网站主机:电子商务主机