思路:
先搞出來每個點的dfs序 (要有入棧和出棧兩種狀態的)
處理出來 線段樹區間有多少入棧的和多少出棧的
加區間的時候就加(入-出)*wei
查字首和
//by siriusren
#include
#include
#include
using namespace std;
#define n 200050
#define int long long
int n,m,wei[n],v[n],first[n],next[n],tot,start[n],end[n],cnt;
int xx,yy,ww,op,tree[n*20],mark[n*20],marka[n*20],vv[n];
void add(int
x,int
y)void dfs(int
x,int fa)
void push_down(int
pos)
void build(int l,int r,int
pos)
int mid=(l+r)>>1,lson=pos
<<1,rson=pos
<<1|1;
build(l,mid,lson),build(mid+1,r,rson);
mark[pos]=mark[lson]+mark[rson];
}void insert(int l,int r,int
pos,int wei,int
x) if(marka[pos])push_down(pos);
int mid=(l+r)>>1,lson=pos
<<1,rson=pos
<<1|1;
if(mid
else insert(l,mid,lson,wei,x);
tree[pos]=tree[lson]+tree[rson];
}int query(int l,int r,int
pos,int
x) if(marka[pos])push_down(pos);
int mid=(l+r)>>1,lson=pos
<<1,rson=pos
<<1|1;
if(mid>=x)return query(l,mid,lson,x);
else
return query(l,mid,lson,x)+query(mid+1,r,rson,x);
}void change(int l,int r,int
pos)
if(marka[pos])push_down(pos);
int mid=(l+r)>>1,lson=pos
<<1,rson=pos
<<1|1;
if(mid1,r,rson);
else
if(mid>=yy)change(l,mid,lson);
else change(l,mid,lson),change(mid+1,r,rson);
tree[pos]=tree[lson]+tree[rson];
}signed main()
else
if(op==2)
else
if(op==3)}}
bzoj 4034 DFS序 線段樹
這個題多了乙個操作難度直線上公升,看完題解才會寫 有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個 操作,分為三種 操作 1 把某個節點 x 的點權增加 a 操作 2 把某個節點 x 為根的子樹中所有點的點權都增加 a 操作 3 詢問某個節點 x 到根的路徑中所有點的點權和。按照...
bzoj4034 樹鏈剖分
time limit 10 sec memory limit 256 mb submit 7576 solved 2597 submit status discuss 有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個 操作,分為三種 操作 1 把某個節點 x 的點權增加 a 操作...
bzoj4034 樹上操作
有一棵點數為 n 的樹,以點 1 為根,且樹點有邊權。然後有 m 個 操作,分為三種 操作 1 把某個節點 x 的點權增加 a 操作 2 把某個節點 x 為根的子樹中所有點的點權都增加 a 操作 3 詢問某個節點 x 到根的路徑中所有點的點權和。第一行包含兩個整數 n,m 表示點數和運算元。接下來一...