P3178 [HAOI2015]树上操作 树链剖分
这个题就是一道树链剖分的裸题,但是需要有一个魔性操作___编号数组需要开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]树上操作 树链剖分的更多相关文章
- bzoj4034[HAOI2015]树上操作 树链剖分+线段树
4034: [HAOI2015]树上操作 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 6163 Solved: 2025[Submit][Stat ...
- bzoj 4034: [HAOI2015]树上操作 树链剖分+线段树
4034: [HAOI2015]树上操作 Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 4352 Solved: 1387[Submit][Stat ...
- 【BZOJ4034】[HAOI2015]树上操作 树链剖分+线段树
[BZOJ4034][HAOI2015]树上操作 Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 ...
- BZOJ4034 [HAOI2015]树上操作 树链剖分
欢迎访问~原文出处——博客园-zhouzhendong 去博客园看该题解 题目传送门 - BZOJ4034 题意概括 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三 ...
- BZOJ4034[HAOI2015]树上操作——树链剖分+线段树
题目描述 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中所有点的点权都 ...
- bzoj 4034: [HAOI2015]树上操作——树链剖分
Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个 操作,分为三种: 操作 1 :把某个节点 x 的点权增加 a . 操作 2 :把某个节点 x 为根的子树中 ...
- BZOJ 4034[HAOI2015]树上操作(树链剖分)
Description 有一棵点数为 N 的树,以点 1 为根,且树点有边权.然后有 M 个操作,分为三种:操作 1 :把某个节点 x 的点权增加 a .操作 2 :把某个节点 x 为根的子树中所有点 ...
- bzoj4034 [HAOI2015]树上操作——树链剖分
题目:https://www.lydsy.com/JudgeOnline/problem.php?id=4034 树剖裸题: 一定要注意 long long !!! update 的时候别忘了 pus ...
- [HAOI2015]树上操作-树链剖分
#include<bits/stdc++.h> using namespace std; const int maxn = 1e6+5; #define mid ((l+r)>> ...
随机推荐
- 关于iframe与$.load()哪个更好
iframe与$.load()哪个更好 iframe可以直接加载页面,但是要付出降低搜索引擎搜索效率的代价,它引入静态文件的方式是完全独立的,简单意思就是,在页面一(父级页面)用ifram ...
- datetimebox赋值或取值
datetimebox赋值或取值 $('#j_dateStart').datebox('setValue', ""); //赋予空值 $("#j_dateStart&qu ...
- Python 字符串常见的用法
line = “ni hao wo jiao key” line.capotalize()#首字母大写 line.center(20)#居中显示固定的字符 line.count('n')#计数,计算该 ...
- 1043 输出PATest (20 分)
题目链接:1043 输出PATest (20 分) 这道题目很简单,遍历整个字符串,统计相应字符的个数,然后按照题目要求进行输出即可. #include <bits/stdc++.h> u ...
- 洛谷——P2018 消息传递
P2018 消息传递 题目描述 巴蜀国的社会等级森严,除了国王之外,每个人均有且只有一个直接上级,当然国王没有上级.如果A是B的上级,B是C的上级,那么A就是C的上级.绝对不会出现这样的关系:A是B的 ...
- UVA - 1601 The Morning after Halloween (双向BFS&单向BFS)
题目: w*h(w,h≤16)网格上有n(n≤3)个小写字母(代表鬼).要求把它们分别移动到对应的大写字母里.每步可以有多个鬼同时移动(均为往上下左右4个方向之一移动),但每步结束之后任何两个鬼不能占 ...
- 洛谷 2471 BZOJ 1067 [SCOI2007]降雨量
[题解] 用线段树维护区间最大值(因为没有修改,St表也可以),然后由于x,y可能是降雨量未知的年份,需要进行分类讨论. #include<cstdio> #include<algo ...
- idea 获取当前git最新分支
菜单栏VCS->选中Git 选择Fetch 获取最新分支
- Spring使用DriverManagerDataSource和C3P0分别配置MySql6.0.6数据源
首先,看一下项目路径 先说spring配置文件吧,这个比较重要 <?xml version="1.0" encoding="UTF-8"?> < ...
- 52. spring boot日志升级篇—log4j多环境不同日志级别的控制【从零开始学Spring Boot】
在上一章节中我们介绍了,仅通过log4j-spring.properties对日志级别进行控制,对于需要多环境部署的环境不是很方便,可能我们在开发环境大部分模块需要采用DEBUG级别,在测试环境可能需 ...