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

本文共 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

你可能感兴趣的文章
CentOS两台服务器利用scp拷贝文件
查看>>
【云计算】Ubuntu14.04 搭建GlusterFS集群
查看>>
SQL DatePart函数使用
查看>>
物联网MQTT协议分析和开源Mosquitto部署验证
查看>>
servlet中的相对路径和绝对路径 及/, ./, ../的区别
查看>>
UpdatePanel无法导出下载文件
查看>>
关于Javascript表单验证
查看>>
LayoutInflater(四)
查看>>
iOS开发之Masonry框架源码解析
查看>>
nginx 静态网站配置
查看>>
iOS 中对 HTTPS 证书链的验证
查看>>
BZOJ2454 : TopCoder SRM 463 RabbitPuzzle
查看>>
按键精灵
查看>>
解释型语言与编译型语言的区别【转】
查看>>
gdb调试python
查看>>
Ubuntu Server如何配置SFTP
查看>>
spring与spring-data-redis整合redis
查看>>
Android 控件EditText的setOnEditorActionListener方法的理解
查看>>
Angular企业级开发(4)-ngResource和REST介绍
查看>>
记首次长途开车回家,本次经历有疏忽也有不顺,但从中学到很多经验
查看>>