有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個操作,分為三種:
操作 1 :把某個節點 x 的點權增加 a 。
操作 2 :把某個節點 x 為根的子樹中所有點的點權都增加 a 。
操作 3 :詢問某個節點 x 到根的路徑中所有點的點權和。
輸入輸出格式
輸入格式:
第一行包含兩個整數 n, m 。表示點數和運算元。接下來一行 n 個整數,表示樹中節點的初始權值。接下來 n-1 行每行兩個正整數 from, to , 表示該樹中存在一條邊 (from, to) 。再接下來 m 行,每行分別表示一次操作。其中第乙個數表示該操作的種類( 1-3 ) ,之後接這個操作的引數( x 或者 x a ) 。
輸出格式:
對於每個詢問操作,輸出該詢問的答案。答案之間用換行隔開。
輸入輸出樣例
輸入樣例#1:
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
輸出樣例#1:
6 9
13好吧,一道裸的樹鏈剖分板子題,嗯,直接上**。
#include
using namespace std;
#define ll long long
const
int maxn=500000+10;
inline ll gi()
#define mid ((l+r)>>1)
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define len (r-l+1)
ll n,m;
struct edgeh[maxn<<1];
ll head[maxn<<1];
ll tot,to[maxn],w[maxn],wt[maxn];
ll a[maxn<<2],laz[maxn<<2];
ll son[maxn],id[maxn],fa[maxn],cnt,dep[maxn],siz[maxn],top[maxn];
ll res=0;
inline
void add(ll u,ll v)
inline
void pushdown(ll rt,ll lenn)
inline
void build(ll rt,ll l,ll r)
build(lson);
build(rson);
a[rt]=(a[rt<<1]+a[rt<<1|1]);
}inline
void query(ll rt,ll l,ll r,ll l,ll r)
else
}inline
void update(ll rt,ll l,ll r,ll l,ll r,ll k)
else
}inline ll qrange(ll x,ll y)
if(dep[x]>dep[y])swap(x,y);
res=0;
query(1,1,n,id[x],id[y]);
ans+=res;
return ans;
}inline
void updson(ll x,ll k)
inline
void dfs1(ll x,ll f,ll deep)
}inline
void dfs2(ll x,ll topf)
}int main()
else
if(k==2)
else
}return
0;}
HAOI2015 樹上操作
題目描述 有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個操作,分為三種 操作 1 把某個節點 x 的點權增加 a 操作 2 把某個節點 x 為根的子樹中所有點的點權都增加 a 操作 3 詢問某個節點 x 到根的路徑中所有點的點權和。輸入格式 第一行包含兩個整數 n,m 表示點數...
HAOI2015 樹上操作
有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個操作,分為三種 操作 1 把某個節點 x 的點權增加 a 操作 2 把某個節點 x 為根的子樹中所有點的點權都增加 a 操作 3 詢問某個節點 x 到根的路徑中所有點的點權和。輸入格式 第一行包含兩個整數 n,m 表示點數和運算元。...
HAOI2015 樹上操作
嘟嘟嘟 樹剖自然可解,就是一道板子題,而且這道題還只問到根節點的距離是多少,而不是樹上任意兩點距離,就更方便了。1 include2 include3 include4 include5 include6 include7 include8 include9 include10 include11 ...