【题目链接】

点击打开链接

【算法】

树链剖分

子树的DFS序是连续的一段!

【代码】

#include<bits/stdc++.h>
using namespace std;
#define MAXN 100010 struct Edge
{
int to,nxt;
} e[MAXN*]; int i,opt,n,m,q,x,y,val,tot,timer;
int dfn[MAXN],pos[MAXN],head[MAXN],size[MAXN],
son[MAXN],top[MAXN],fa[MAXN],dep[MAXN];
long long a[MAXN]; template <typename T> inline void read(T &x)
{
long long f = ; x = ;
char c = getchar();
for (; !isdigit(c); c = getchar()) { if (c == '-') f = -f; }
for (; isdigit(c); c = getchar()) x = (x << ) + (x << ) + c - '';
x *= f;
}
template <typename T> inline void write(T x)
{
if (x < )
{
putchar('-');
x = -x;
}
if (x > ) write(x/);
putchar(x%+'');
}
template <typename T> inline void writeln(T x)
{
write(x);
puts("");
} struct SegmentTree
{
struct Node
{
int l,r;
long long sum,tag;
} Tree[MAXN*];
inline void update(int index)
{
Tree[index].sum = Tree[index<<].sum + Tree[index<<|].sum;
}
inline void pushdown(int index)
{
int l = Tree[index].l,r = Tree[index].r;
int mid = (l + r) >> ;
if (Tree[index].tag)
{
Tree[index<<].sum += Tree[index].tag * (mid - l + );
Tree[index<<|].sum += Tree[index].tag * (r - mid);
Tree[index<<].tag += Tree[index].tag;
Tree[index<<|].tag += Tree[index].tag;
Tree[index].tag = ;
}
}
inline void build(int index,int l,int r)
{
int mid;
Tree[index].l = l;
Tree[index].r = r;
if (l == r)
{
Tree[index].sum = a[pos[l]];
return;
}
mid = (l + r) >> ;
build(index<<,l,mid);
build(index<<|,mid+,r);
update(index);
}
inline void add1(int index,int pos,long long val)
{
int mid;
if (Tree[index].l == Tree[index].r)
{
Tree[index].sum += val;
return;
}
pushdown(index);
mid = (Tree[index].l + Tree[index].r) >> ;
if (mid >= pos) add1(index<<,pos,val);
else add1(index<<|,pos,val);
update(index);
}
inline void add2(int index,int l,int r,long long val)
{
int mid;
if (Tree[index].l == l && Tree[index].r == r)
{
Tree[index].sum += val * (r - l + );
Tree[index].tag += val;
return;
}
pushdown(index);
mid = (Tree[index].l + Tree[index].r) >> ;
if (mid >= r) add2(index<<,l,r,val);
else if (mid + <= l) add2(index<<|,l,r,val);
else
{
add2(index<<,l,mid,val);
add2(index<<|,mid+,r,val);
}
update(index);
}
inline long long query(int index,int l,int r)
{
int mid;
if (Tree[index].l == l && Tree[index].r == r) return Tree[index].sum;
pushdown(index);
mid = (Tree[index].l + Tree[index].r) >> ;
if (mid >= r) return query(index<<,l,r);
else if (mid + <= l) return query(index<<|,l,r);
else return query(index<<,l,mid) + query(index<<|,mid+,r);
}
} T; inline void add(int u,int v)
{
tot++;
e[tot] = (Edge){v,head[u]};
head[u] = tot;
}
inline void dfs1(int x)
{
int i,y;
size[x] = ;
for (i = head[x]; i; i = e[i].nxt)
{
y = e[i].to;
if (fa[x] != y)
{
fa[y] = x;
dep[y] = dep[x] + ;
dfs1(y);
size[x] += size[y];
if (size[y] > size[son[x]]) son[x] = y;
}
}
}
inline void dfs2(int x,int tp)
{
int i,y;
top[x] = tp;
dfn[x] = ++timer;
pos[timer] = x;
if (son[x]) dfs2(son[x],tp);
for (i = head[x]; i; i = e[i].nxt)
{
y = e[i].to;
if (fa[x] != y && son[x] != y) dfs2(y,y);
}
}
inline long long query(int x)
{
long long ans = ;
int tx = top[x];
while (tx != )
{
ans += T.query(,dfn[tx],dfn[x]);
x = fa[tx]; tx = top[x];
}
ans += T.query(,,dfn[x]);
return ans;
} int main() { read(n); read(q);
for (i = ; i <= n; i++) read(a[i]);
for (i = ; i < n; i++)
{
read(x); read(y);
add(x,y);
add(y,x);
}
dfs1();
dfs2(,); T.build(,,timer);
while (q--)
{
read(opt);
if (opt == )
{
read(x); read(val);
T.add1(,dfn[x],val);
}
if (opt == )
{
read(x); read(val);
T.add2(,dfn[x],dfn[x]+size[x]-,val);
}
if (opt == )
{
read(x);
writeln(query(x));
}
} return ; }

最新文章

  1. Servlet中以HashMap存放临时变量,解决跳转新页面请求参数过多时浏览器地址栏超长
  2. NopCommerce 增加 Customer Settings
  3. Android调用系统照相机
  4. 记录自己在使用Bootstrap中的心得
  5. c#开发Mongo笔记第二篇
  6. windows网络版象棋的实现
  7. STL--set
  8. JQuery.tmpl()的用法
  9. poj3393[模拟题]
  10. struts1与struts2的区别
  11. OC与JS互相调用
  12. Android获取当前时间与星期几
  13. 基于Visual C++2013拆解世界五百强面试题--题1-定义各种类型指针
  14. python--sum函数--sum(axis=1)
  15. Elasticsearch高级搜索排序( 中文+拼音+首字母+简繁转换+特殊符号过滤)
  16. 用java写一个用户登陆界面
  17. Sublime text 3编辑python时出现方框的解决办法
  18. JIRA开启时间追踪并为问题记录工作日志
  19. Daily Scrum- 12/23
  20. C# 生成一个带数字的饼图

热门文章

  1. HDU 1078 dfs+dp
  2. HDU1686 计算模式串匹配的次数
  3. hdu4514(非连通图的环判断与图中最长链)(树的直径)
  4. idea添加虚拟参数
  5. Android菜单
  6. usort 使用(转载)
  7. uva 11691
  8. HDU 5280 Senior&amp;#39;s Array
  9. 矩阵奇异值分解(SVD)
  10. JAVA数组去除重复数据