# [BZOJ4034][HAOI2015]树上操作

## 4034: [HAOI2015]树上操作

Time Limit: 10 Sec  Memory Limit: 256 MB
Submit: 5752  Solved: 1850
[Submit][Status][Discuss]

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

6
9
13

## HINT

对于 100% 的数据， N,M<=100000 ，且所有输入数据的绝对值都不会超过 10^6 。

#include <cstdio>
#include <algorithm>
using namespace std;
char buf[10000000], *ptr = buf - 1;
int n = 0;
bool flag = false;
while(*++ptr < '0' || *ptr > '9') if(*ptr == '-') flag = true;
while(*ptr >= '0' && *ptr <= '9') n = (n << 1) + (n << 3) + (*ptr++ & 15);
return flag ? -n : n;
}
typedef long long ll;
const int maxn = 100000 + 10;
int n, m;
struct Edge{
int to, next;
Edge(){}
Edge(int _t, int _n): to(_t), next(_n){}
}e[maxn * 2];
int fir[maxn] = {0}, cnt = 0;
inline void ins(int u, int v){
e[++cnt] = Edge(v, fir[u]); fir[u] = cnt;
e[++cnt] = Edge(u, fir[v]); fir[v] = cnt;
}
int fa[maxn], siz[maxn], son[maxn];
void dfs1(int u){
siz[u] = 1;
son[u] = 0;
for(int v, i = fir[u]; i; i = e[i].next){
v = e[i].to;
if(v == fa[u]) continue;
fa[v] = u;
dfs1(v);
siz[u] += siz[v];
if(!son[u] || siz[v] > siz[son[u]]) son[u] = v;
}
}
int val[maxn], w[maxn], top[maxn], in[maxn], out[maxn], dfs_idx = 0;
void dfs2(int u){
in[u] = ++dfs_idx;
w[dfs_idx] = val[u];
if(!son[u]){
out[u] = dfs_idx;
return;
}
top[son[u]] = top[u];
dfs2(son[u]);
for(int v, i = fir[u]; i; i = e[i].next){
v = e[i].to;
if(v == fa[u] || v == son[u]) continue;
top[v] = v;
dfs2(v);
}
out[u] = dfs_idx;
}
#define lson l, mid, rt << 1
#define rson mid + 1, r, rt << 1 | 1
ll sum[maxn * 4], tag[maxn * 4] = {0};
inline void pushup(int rt){
sum[rt] = sum[rt << 1] + sum[rt << 1 | 1];
}
void build(int l, int r, int rt){
if(l == r) sum[rt] = w[l];
else{
int mid = l + r >> 1;
build(lson);
build(rson);
pushup(rt);
}
}
inline void pushdown(int rt, int m){
if(tag[rt]){
sum[rt << 1] += tag[rt] * (m - (m >> 1));
sum[rt << 1 | 1] += tag[rt] * (m >> 1);
tag[rt << 1] += tag[rt];
tag[rt << 1 | 1] += tag[rt];
tag[rt] = 0;
}
}
int ql, qr, qv;
inline void update(int l, int r, int rt){
if(ql <= l && r <= qr){
sum[rt] += (ll)qv * (r - l + 1);
tag[rt] += qv;
}
else{
pushdown(rt, r - l + 1);
int mid = l + r >> 1;
if(ql <= mid) update(lson);
if(qr > mid) update(rson);
pushup(rt);
}
}
inline ll query(int l, int r, int rt){
if(ql <= l && r <= qr) return sum[rt];
else{
pushdown(rt, r - l + 1);
int mid = l + r >> 1;
ll ret = 0;
if(ql <= mid) ret += query(lson);
if(qr > mid) ret += query(rson);
return ret;
}
}
ll ans = 0;
while(top[x] != 1){
ql = in[top[x]];
qr = in[x];
ans += query(1, n, 1);
x = fa[top[x]];
}
ql = in[1];
qr = in[x];
ans += query(1, n, 1);
printf("%lld\n", ans);
}
int main(){
buf[fread(buf, sizeof(char), sizeof(buf), stdin)] = 0;
for(int i = 1; i <= n; i++) val[i] = readint();
fa[1] = 0;
dfs1(1);
top[1] = 1;
dfs2(1);
build(1, n, 1);
int opt, x;
while(m--){
if(opt == 1){
ql = qr = in[x];
update(1, n, 1);
}
else if(opt == 2){
ql = in[x];
qr = out[x];
update(1, n, 1);
}
}
return 0;
} 

posted @ 2017-10-14 23:43  Elder_Giang  阅读(101)  评论(0编辑  收藏  举报