博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
HDU - 3966-Aragorn' Story(树链剖分+线段树)
阅读量:6907 次
发布时间:2019-06-27

本文共 4062 字,大约阅读时间需要 13 分钟。

链接:

题意:

Our protagonist is the handsome human prince Aragorn comes from The Lord of the Rings. One day Aragorn finds a lot of enemies who want to invade his kingdom. As Aragorn knows, the enemy has N camps out of his kingdom and M edges connect them. It is guaranteed that for any two camps, there is one and only one path connect them. At first Aragorn know the number of enemies in every camp. But the enemy is cunning , they will increase or decrease the number of soldiers in camps. Every time the enemy change the number of soldiers, they will set two camps C1 and C2. Then, for C1, C2 and all camps on the path from C1 to C2, they will increase or decrease K soldiers to these camps. Now Aragorn wants to know the number of soldiers in some particular camps real-time.

思路:

第一次写树链剖分, 直接上模板。

代码:

#include 
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
using namespace std;typedef long long LL;const int MAXN = 5e4+10;vector
G[MAXN];int Dis[MAXN], Fa[MAXN], Top[MAXN], Size[MAXN];int Son[MAXN], Id[MAXN], Rk[MAXN];int Seg[MAXN*4], A[MAXN], Add[MAXN*4];int n, m, p;int x, y;int cnt = 0;void Init(){ for (int i = 1;i <= n;i++) G[i].clear(); memset(Seg, 0, sizeof(Seg)); memset(Son, 0, sizeof(Son)); memset(Add, 0, sizeof(Add)); cnt = 0;}void Dfs1(int x, int u, int dep){ Dis[u] = dep; Fa[u] = x; Size[u] = 1; for (int i = 0;i < G[u].size();i++) { int v = G[u][i]; if (v == x) continue; Dfs1(u, v, dep+1); Size[u] += Size[v]; if (Size[v] > Size[Son[u]]) Son[u] = v; }}void Dfs2(int u, int top){ Top[u] = top; Id[u] = ++cnt; Rk[cnt] = u; if (!Son[u]) return; Dfs2(Son[u], top); for (int i = 0;i < G[u].size();i++) { int v = G[u][i]; if (v != Son[u] && v != Fa[u]) Dfs2(v, v); }}void PushUp(int root){ Seg[root] = Seg[root<<1]+Seg[root<<1|1];}void PushDown(int root, int l, int r){ if (Add[root]) { int mid = (l+r)/2; Add[root<<1] += Add[root]; Add[root<<1|1] += Add[root]; Seg[root<<1] += (mid-l+1)*Add[root]; Seg[root<<1|1] += (r-mid)*Add[root]; Add[root] = 0; }}void Build(int root, int l, int r){ if (l == r) { Seg[root] = A[Rk[l]]; return; } int mid = (l+r)/2; Build(root<<1, l, mid); Build(root<<1|1, mid+1, r); PushUp(root);}int Query(int root, int l, int r, int ql, int qr){ if (r < ql || qr < l) return 0; if (ql <= l && r <= qr) return Seg[root]; PushDown(root, l, r); int mid = (l+r)/2; int res = 0; res += Query(root<<1, l, mid, ql, qr); res += Query(root<<1|1, mid+1, r, ql, qr); PushUp(root); return res;}void Update(int root, int l, int r, int ql, int qr, int c){ if (r < ql || qr < l) return; if (ql <= l && r <= qr) { Seg[root] += (r-l+1)*c; Add[root] += c; return; } PushDown(root, l, r); int mid = (l+r)/2; Update(root<<1, l, mid, ql, qr, c); Update(root<<1|1, mid+1, r, ql, qr, c); PushUp(root);}void UpdateLine(int l, int r, int c){ while (Top[l] != Top[r]) { if (Dis[Top[l]] < Dis[Top[r]]) swap(l, r); Update(1, 1, n, Id[Top[l]], Id[l], c); l = Fa[Top[l]]; } if (Id[l] < Id[r]) Update(1, 1, n, Id[l], Id[r], c); else Update(1, 1, n, Id[r], Id[l], c);}int main(){// freopen("test.in", "r", stdin); while (~scanf("%d%d%d", &n, &m, &p)) { Init(); for (int i = 1;i <= n;i++) scanf("%d", &A[i]); for (int i = 1;i < n;i++) { scanf("%d%d", &x, &y); G[x].push_back(y); G[y].push_back(x); } Dfs1(0, 1, 1); Dfs2(1, 1); Build(1, 1, n);// for (int i = 1;i <= n;i++)// cout << Dis[i] << ' ';// cout << endl;// for (int i = 1;i <= n;i++)// cout << Id[i] << ' ';// cout << endl;// for (int i = 1;i <= n;i++)// cout << Top[i] << ' ' ;// cout << endl; char op[10]; int l, r, v, w; while (p--) { scanf("%s", op); if (op[0] == 'I') { scanf("%d%d%d", &l, &r, &v);// cout << Top[l] << ' ' << Top[r] << endl; UpdateLine(l, r, v); } else if (op[0] == 'D') { scanf("%d%d%d", &l, &r, &v); v = -v; UpdateLine(l, r, v); } else { scanf("%d", &w); printf("%d\n", Query(1, 1, n, Id[w], Id[w])); } } } return 0;}

  

转载于:https://www.cnblogs.com/YDDDD/p/10971403.html

你可能感兴趣的文章
参考_Android中,如何新建一个界面,并且实现从当前界面切换到到刚才新建的(另外一个)界面...
查看>>
Linux常用命令大全
查看>>
Jenkins卸载方法(Windows/Linux/MacOS)
查看>>
《过节》——北岛
查看>>
并发、并行、同步、异步、多线程的区别?
查看>>
JavaScript的写类方式(5)——转
查看>>
Java并发编程笔记—摘抄—基础知识
查看>>
simple-spring-memcached统一缓存的使用实例
查看>>
Codeforces 600E - Lomsat gelral(树上启发式合并)
查看>>
[Hnoi2013]消毒
查看>>
[HNOI2015]开店
查看>>
容斥与反演
查看>>
GitHub 配置指南
查看>>
swift swift学习笔记--函数和闭包
查看>>
Java 面向对象,封装,继承
查看>>
ISO语言代码
查看>>
一文搞懂List 、List<Object>、List<?>的区别以及<? extends T>与<? super T>的区别
查看>>
Java 读写Properties配置文件
查看>>
17.自定义指令
查看>>
使用Maven构建多模块项目
查看>>