这个题就是一道树链剖分的裸题,但是需要有一个魔性操作___编号数组需要开longlong!!!震惊!真的神奇.

题干:

题目描述

有一棵点数为 N 的树,以点  为根,且树点有边权。然后有 M 个操作,分为三种:操作  :把某个节点 x 的点权增加 a 。操作  :把某个节点 x 为根的子树中所有点的点权都增加 a 。操作  :询问某个节点 x 到根的路径中所有点的点权和。
输入输出格式
输入格式: 第一行包含两个整数 N, M 。表示点数和操作数。接下来一行 N 个整数,表示树中节点的初始权值。接下来 N- 行每行两个正整数 from, to , 表示该树中存在一条边 (from, to) 。再接下来 M 行,每行分别表示一次操作。其中第一个数表示该操作的种类( - ) ,之后接这个操作的参数( x 或者 x a ) 。
输出格式:
对于每个询问操作,输出该询问的答案。答案之间用换行隔开。
输入输出样例
输入样例#: 复制 输出样例#: 复制 说明
对于 % 的数据, N,M<= ,且所有输入数据的绝对值都不
会超过 ^ 。

代码:

#include<iostream>
#include<cstdio>
#include<cmath>
#include<ctime>
#include<queue>
#include<algorithm>
#include<cstring>
using namespace std;
#define duke(i,a,n) for(int i = a;i <= n;i++)
#define lv(i,a,n) for(int i = a;i >= n;i--)
#define clean(a) memset(a,0,sizeof(a))
const int INF = << ;
typedef long long ll;
typedef double db;
template <class T>
void read(T &x)
{
char c;
bool op = ;
while(c = getchar(), c < '' || c > '')
if(c == '-') op = ;
x = c - '';
while(c = getchar(), c >= '' && c <= '')
x = x * + c - '';
if(op) x = -x;
}
template <class T>
void write(T x)
{
if(x < ) putchar('-'), x = -x;
if(x >= ) write(x / );
putchar('' + x % );
}
const int N = ;
struct node
{
ll l,r;
int nxt;
}a[N];
int len = ,lst[N];
void add(ll x,ll y)
{
a[++len].l = x;
a[len].r = y;
a[len].nxt = lst[x];
lst[x] = len;
}
ll n,m;
ll tree[N << ],lazy[N << ];
ll siz[N],son[N],cnt = ,id[N];
ll A[N];
ll top[N],f[N],rk[N],dep[N];
int vis[N];
void dfs1(ll u,ll fa,ll depth)
{
f[u] = fa;
siz[u] = ;
dep[u] = depth;
for(int k = lst[u];k;k = a[k].nxt)
{
ll y = a[k].r;
if(y == fa) continue;
dfs1(y,u,depth + );
siz[u] += siz[y];
if(!son[u] || siz[son[u]] < siz[y])
son[u] = y;
}
}
void dfs2(ll u,ll t)
{
vis[u] = ;
top[u] = t;
id[u] = ++cnt;
rk[cnt] = u;
if(!son[u]) return;
dfs2(son[u],t);
for(int k = lst[u];k;k = a[k].nxt)
{
ll y = a[k].r;
if(y == son[u] || y == f[u] || vis[y] == )
continue;
dfs2(y,y);
}
}
void build(ll o,ll l,ll r)
{
if(l == r)
{
tree[o] = A[rk[l]];
return;
}
ll mid = (l + r) >> ;
build(o << ,l,mid);
build(o << | ,mid + ,r);
tree[o] = tree[o << ] + tree[o << | ];
}
void push_down(ll o,ll l,ll r)
{
if(lazy[o] != )
{
ll mid = (l + r) >> ;
tree[o << ] += (ll)(mid - l + ) * lazy[o];
tree[o << | ] += (ll)(r - mid) * lazy[o];
lazy[o << ] += lazy[o];
lazy[o << | ] += lazy[o];
lazy[o] = ;
}
}
void sin_change(ll o,ll l,ll r,ll k,ll w)
{
if(l == r)
{
tree[o] += w;
lazy[o] += w;
return;
}
ll mid = (l + r) >> ;
push_down(o,l,r);
if(mid >= k)
sin_change(o << ,l,mid,k,w);
else
sin_change(o << | ,mid + ,r,k,w);
}
void all_change(ll o,ll l,ll r,ll x,ll y,ll w)
{
if(l == x && r == y)
{
tree[o] += (r - l + ) * w;
lazy[o] += w;
return;
}
push_down(o,l,r);
ll mid = (l + r) >> ;
if(mid >= y)
all_change(o << ,l,mid,x,y,w);
else if(mid < x)
all_change(o << | ,mid + ,r,x,y,w);
else
{
all_change(o << ,l,mid,x,mid,w);
all_change(o << | ,mid + ,r,mid + ,y,w);
}
tree[o] = tree[o << ] + tree[o << | ];
}
ll query(ll o,ll l,ll r,ll x,ll y)
{
if(l == x && r == y)
return tree[o];
push_down(o,l,r);
ll mid = (l + r) >> ;
if(mid >= y)
return query(o << ,l,mid,x,y);
else if(mid < x)
return query(o << | ,mid + ,r,x,y);
else
{
ll ans = ;
ans += query(o << ,l,mid,x,mid);
ans += query(o << | ,mid + ,r,mid + ,y);
return ans;
}
}
ll work(int x,int y)
{
ll ans = ;
while(top[x] != top[y])
{
if(dep[top[x]] < dep[top[y]])
swap(x,y);
ll res = query(,,n,id[top[x]],id[x]);
ans += res;
x = f[top[x]];
}
if(dep[x] > dep[y])
swap(x,y);
ans += query(,,n,id[x],id[y]);
return ans;
}
int main()
{
read(n);read(m);
duke(i,,n)
read(A[i]);
duke(i,,n - )
{
ll x,y;
read(x);read(y);
add(x,y);
add(y,x);
}
dfs1(,,);
dfs2(,);
int ok;
build(,,n);
/*duke(i,1,n)
printf("%d ",top[i]);
cout<<endl;*/
/*duke(i,1,n)
printf("%d ",tree[i]);
cout<<endl;*/
duke(i,,m)
{
read(ok);
if(ok == )
{
ll x;ll y;
read(x);read(y);
all_change(,,n,id[x],id[x],y);
}
else if(ok == )
{
ll x;ll y;
read(x);read(y);
all_change(,,n,id[x],id[x] + siz[x] - ,y);
}
else
{
ll x;
read(x);//printf("!!!%d %d\n",id[1],id[x]);
printf("%lld\n",work(,x));
}
/*duke(i,1,n)
printf("%d ",lazy[i]);
cout<<endl;*/
}
return ;
}
/*
5 5
1 2 3 4 5
1 2
1 4
2 3
2 5
3 3
1 2 1
3 5
2 1 2
3 3
*/

P3178 [HAOI2015]树上操作 树链剖分的更多相关文章

  1. bzoj4034[HAOI2015]树上操作 树链剖分+线段树

    4034: [HAOI2015]树上操作 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 6163  Solved: 2025[Submit][Stat ...

  2. bzoj 4034: [HAOI2015]树上操作 树链剖分+线段树

    4034: [HAOI2015]树上操作 Time Limit: 10 Sec  Memory Limit: 256 MBSubmit: 4352  Solved: 1387[Submit][Stat ...

  3. 【BZOJ4034】[HAOI2015]树上操作 树链剖分+线段树

    [BZOJ4034][HAOI2015]树上操作 Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 ...

  4. BZOJ4034 [HAOI2015]树上操作 树链剖分

    欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ4034 题意概括 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三 ...

  5. BZOJ4034[HAOI2015]树上操作——树链剖分+线段树

    题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都 ...

  6. bzoj 4034: [HAOI2015]树上操作——树链剖分

    Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中 ...

  7. BZOJ 4034[HAOI2015]树上操作(树链剖分)

    Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点 ...

  8. bzoj4034 [HAOI2015]树上操作——树链剖分

    题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4034 树剖裸题: 一定要注意 long long !!! update 的时候别忘了 pus ...

  9. [HAOI2015]树上操作-树链剖分

    #include<bits/stdc++.h> using namespace std; const int maxn = 1e6+5; #define mid ((l+r)>> ...

随机推荐

  1. CAD插入图片

    在CAD设计绘图时,需要插入外部图片,可以设置图片的缩放比例.旋转角度.图片显示文件名等属性. 主要用到函数说明: _DMxDrawX::DrawImageMark 绘图制一个图象标记对象.详细说明如 ...

  2. 初步认识MVC

     一丶路由(One) 自定义路由,静态路由,动态路由,组合路由 routes.MapRoute 二丶Action向View传值的四种方式(ViewData.ViewBag.TempData.Model ...

  3. CentOS7 安装 PHP7.2

    点击查看原文 安装源 安装 EPEL 软件包: $ sudo yum install epel-release 安装 remi 源: $ sudo yum install http://rpms.re ...

  4. 作为一个程序员,分享一下我自己常用的几款非常方便的chrome插件

    作为一名资深码农,结合身边一群IT民工的真实体验,小编有那么一点权威给各位推荐几款程序员必备.常用的chrome扩展插件. 1.Click&Clean Click&Clean插件可以监 ...

  5. Java 数组中寻找最大子数组

    程序设计思想: 依次将数组划分开,先判断一个元素的单个数组大小,接下来两个,依次上升,最后将所得结果进行比较赋值,输出最大结果. 1 package ketangTest; //张生辉,康治家 201 ...

  6. Extract local angle of attack on wind turbine blades

    Extract local angle of attack on wind turbine blades Table of Contents 1. Extract local angle of att ...

  7. flex多列布局遇到的问题,和解决方案

    flex布局无疑是简单.易用的,他让我我们的布局更加简单和快速,但是在使用flex进行多列布局的时候,我相信很多人会遇到下面的情况: 这种情况是因为我们使用了justify-content: spac ...

  8. Andrew and Chemistry(树的同构)

    Andrew and Chemistry(树的同构) 题链 将一棵树转化为最小表示法,将此时的树哈希一下,同时用map进行标记,就可以判断树是否存在同构 #include <map> #i ...

  9. Codeforces 990D - Graph And Its Complement

    传送门:http://codeforces.com/contest/990/problem/D 这是一个构造问题. 构造一张n阶简单无向图G,使得其连通分支个数为a,且其补图的连通分支个数为b. 对于 ...

  10. 终于又弄完一个DJANGO BY EXAMPLE的测试

    感觉学到了很多东东,都是以前开发不曾用到的. 知识的作用是到用时,知道到哪里去查相关的功能..:) 这个bookmarks就有很多功能点值得学习呢...