# [bzoj4034] [HAOI2015]树上操作

## Sample Input

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


## Sample Output

6
9
13


## solution

#include<bits/stdc++.h>
#define int long long
using namespace std;

x=0;int f=1;char ch=getchar();
for(;!isdigit(ch);ch=getchar()) if(ch=='-') f=-f;
for(;isdigit(ch);ch=getchar()) x=x*10+ch-'0';x*=f;
}

void print(int x) {
if(x<0) x=-x,putchar('-');
if(!x) return ;print(x/10),putchar(x%10+48);
}
void write(int x) {if(!x) putchar('0');else print(x);puts("");}

const int maxn = 1e5+10;

struct edge{int to,nxt;}e[maxn<<1];

#define ls p<<1
#define rs p<<1|1
#define mid ((l+r)>>1ll)

struct Segment_Tree {
int tr[maxn<<2],tag[maxn<<2];
void update(int p) {tr[p]=tr[ls]+tr[rs];}
void pushdown(int p,int l,int r) {
if(!tag[p]) return ;
tag[ls]+=tag[p],tag[rs]+=tag[p];
tr[ls]+=tag[p]*(mid-l+1),tr[rs]+=tag[p]*(r-mid);tag[p]=0;
}
void modify(int p,int l,int r,int x,int y,int v) {
if(x<=l&&r<=y) return tag[p]+=v,tr[p]+=v*(r-l+1),void();
pushdown(p,l,r);
if(x<=mid) modify(ls,l,mid,x,y,v);
if(y>mid) modify(rs,mid+1,r,x,y,v);
update(p);
}
int query(int p,int l,int r,int x,int y) {
if(x<=l&&r<=y) return tr[p];
pushdown(p,l,r);int ans=0;
if(x<=mid) ans+=query(ls,l,mid,x,y);
if(y>mid) ans+=query(rs,mid+1,r,x,y);
return ans;
}
}SGT;

struct Heavy_Light_Decomposition {
void dfs1(int x,int fa) {
dep[x]=dep[fa]+1;sz[x]=1;f[x]=fa;
if(e[i].to!=fa) {
dfs1(e[i].to,x),sz[x]+=sz[e[i].to];
if(sz[hs[x]]<sz[e[i].to]) hs[x]=e[i].to;
}
}
void dfs2(int x) {
dfn[x]=++dfn_cnt;
if(hs[f[x]]==x) top[x]=top[f[x]];
else top[x]=x;
if(hs[x]) dfs2(hs[x]);
if(e[i].to!=f[x]&&e[i].to!=hs[x]) dfs2(e[i].to);
}
int query(int x) {
int ans=0;
while(x) {
ans+=SGT.query(1,1,n,dfn[top[x]],dfn[x]);
x=f[top[x]];
}
return ans;
}
}HLD;

signed main() {