这个题就是一道树链剖分的裸题,但是需要有一个魔性操作___编号数组需要开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. 初步认识MVC

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

  2. Extjs选中多行Grid提交

    要实现的效果如图:可以选择多行grid然后提交给后台 1,Extjs中grid如何可以选择多行? 定义一个grid,将色了Type设置为多选即可 selType: 'checkboxmodel', 2 ...

  3. css去掉div的滚动条

    懒得讲原理了,直接贴代码: css部分: .slide-box { margin-top: 200px; display: -webkit-box; overflow-x: scroll; overf ...

  4. cc.Node—事件响应

    触摸事件1: 触摸事件类型: START, MOVED, ENDED(物体内), CANCEL(物体外);2: 监听触摸事件: node.on(类型, callback, target(回掉函数的th ...

  5. 洛谷——P3871 [TJOI2010]中位数

    P3871 [TJOI2010]中位数 一眼秒掉,这不是splay水题吗,套模板 #include<bits/stdc++.h> #define IL inline #define N 1 ...

  6. http怎么做自动跳转https

    Nginx版本 server { listen       80; server_name  localhost; rewrite ^(.*)$ https://$host$1 permanent; ...

  7. buf.writeUInt32BE()

    buf.writeUInt32BE(value, offset[, noAssert]) buf.writeUInt32LE(value, offset[, noAssert]) value {Num ...

  8. CCF201609-2 火车购票 java(100分)

    试题编号: 201609-2 试题名称: 火车购票 时间限制: 1.0s 内存限制: 256.0MB 问题描述: 问题描述 请实现一个铁路购票系统的简单座位分配算法,来处理一节车厢的座位分配. 假设一 ...

  9. Webstorm如何配置自动补全前缀--autoprefixer

    我们在写样式代码时,对不同平台会有不同的兼容性写法,会在代码前加前缀,但是手动加前缀很费时间而且很容易弄错.Webstorm编辑器是有自带补全前缀功能的,那为什么还要写这篇配置博客,因为Webstor ...

  10. 【03】AngularJS 简介

    AngularJS 简介 AngularJS 是一个 JavaScript 框架.它可通过 <script> 标签添加到 HTML 页面. AngularJS 通过 指令 扩展了 HTML ...