樹鏈剖分的**實在是長,少有的幾次**行數過百了
線段樹 在圖論裡面的應用
線段樹是處理區間問題的
在圖論的樹裡面的應用就是通過重鏈的方式dfs編號,形成一段連續的區間,就可以用線段樹來處理了;
能做到的事情為
如題,已知一棵包含n個結點的樹(連通且無環),每個節點上包含乙個數值,需要支援以下操作:
操作1: 格式: 1 x y z 表示將樹從x到y結點最短路徑上所有節點的值都加上z
操作2: 格式: 2 x y 表示求樹從x到y結點最短路徑上所有節點的值之和
操作3: 格式: 3 x z 表示將以x為根節點的子樹內所有節點值都加上z
操作4: 格式: 4 x 表示求以x為根節點的子樹內所有節點值之和
#include #include #include using namespace std;
const int maxn=1e5+7;
struct nodeseg[maxn<<2];
int h[maxn],e[maxn<<1],ne[maxn<<1],idx;
int w[maxn],id[maxn],cnt,w2[maxn],deep[maxn],fa[maxn],siz[maxn],son[maxn],top[maxn];
int n,m,root,mod;
void add(int a,int b)
void dfs1(int x,int f)
}void dfs2(int x,int topf)
}void push_down(int p)
void build(int p,int l,int r)
int mid=l+r>>1;
build(p<<1,l,mid);build(p<<1|1,mid+1,r);
seg[p].sum=(seg[p<<1].sum+seg[p<<1|1].sum)%mod;
}int query(int p,int l,int r)
void change(int p,int l,int r,int d)
push_down(p);
if(l<=mid)change(p<<1,l,r,d);
if(mid+1<=r)change(p<<1|1,l,r,d);
seg[p].sum=(seg[p<<1].sum+seg[p<<1|1].sum)%mod;
}int q_range(int x,int y)
void add_range(int x,int y,int d)
int main()
else if(op==2)else if(op==3)else if(op==4)
}return 0;
}
P3384 模板 樹鏈剖分
傳送門 題目描述 如題,已知一棵包含n個結點的樹 連通且無環 每個節點上包含乙個數值,需要支援以下操作 操作1 格式 1 x y z 表示將樹從x到y結點最短路徑上所有節點的值都加上z 操作2 格式 2 x y 表示求樹從x到y結點最短路徑上所有節點的值之和 操作3 格式 3 x z 表示將以x為根...
P3384 模板 樹鏈剖分
p3384 模板 樹鏈剖分 樹鏈剖分是把一棵樹劃分成幾條鏈,這幾條鏈又能組成陣列,然後把陣列建成線段樹,繼而相當於在樹樹上操作。include include include include include using namespace std const int maxn 2e5 10 int ...
P3384 模板 樹鏈剖分
題目描述 如題,已知一棵包含n個結點的樹 連通且無環 每個節點上包含乙個數值,需要支援以下操作 操作1 格式 1 x y z 表示將樹從x到y結點最短路徑上所有節點的值都加上z 操作2 格式 2 x y 表示求樹從x到y結點最短路徑上所有節點的值之和 操作3 格式 3 x z 表示將以x為根節點的子...