對一棵樹進行操作,1 v x k代表對根節點v加x,對v的子節點加x-k,對孫子節點加v-2k。2 v代表查詢節點v的值。
其實是乙個很簡單的線段樹,對於一次增加操作,節點x增加的值其實就是x-(deep[x]-deep[v])*k。(deep[v]為該次修改的根節點)。查詢的時候單點查詢,也不用pushdown,直接再遞迴返回的時候加上中間節點的值就可以了。
需要求dfs序,需要特別注意末節點end的位置是pos-1,而不是pos,因為末節點在賦值後pos++了。
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#include
#define up(i,l,h) for(int i=l;i#define down(i,h,l) for(int i=h-1;i>=l;i--)
#define w(a) while(a)
#define mem(a,b) memset(a,b,sizeof(a))
#define inf 0x3f3f3f3f3f3f3f3f
#define ll long long
#define maxn 300010
#define size 95
#define eps 1e-10
#define mod 1000000007
#define int ll
using
namespace
std;
struct node;
node nodes[maxn*4];
vector
son[maxn];
int lt,rt,v,k;
int st[maxn],ed[maxn],dep[maxn];
int u;
int pos,deep;
void dfs(int x)
deep--;
ed[x]=pos-1;
}void update(int o,int l,int r)else
if(rt>m)
}}int query(int o,int l,int r)elseelse
}}main()
pos=1;
deep=0;
int p;
up(i,1,n)
dfs(1);
mem(nodes,0);
int q;
scanf("%i64d",&q);
w(q--)else}}
}
dfs序 線段樹
傳送門 現有一棵樹,有以下操作 1.節點x及其所有子孫顏色都變更為k。2.要求你回答節點x的顏色。初始所有點都沒有染色。input 第一行乙個整數t t 10 表示樣例組數。對於每個測試樣例 第一行乙個整數n n 5e4 表示樹的節點個數。接下來n行,每行兩個整數u,v 1 u,v n 表示樹中u的...
HDU snacks (線段樹 dfs序)
problem description input 輸入資料第一行是乙個整數,表示有組測試資料。對於每組資料,包含兩個整數,表示有個零食機,次操作。接下來行,每行兩個整數和,表示編號為的零食機與編號為的零食機相連。接下來一行由個數組成,表示從編號為0到編號為的零食機的初始價值。接下來行,有兩種操作 ...
求和(dfs序 線段樹)
題意 已知有n個節點,有n 1條邊,形成乙個樹的結構。給定乙個根節點k,每個節點都有乙個權值,節點i的權值為vi 給m個操作,操作有兩種型別 1 a x 表示將節點a的權值加上x 2 a 表示求a節點的子樹上所有節點的和 包括a節點本身 題解 dfs序 線段樹 用dfs序確定in x 和out x ...