題目描述:戳這裡
題解:
其實樹剖的重點就在於輕重鏈,這篇文章寫的很好
然而我線段樹寫得全是問題,改了半天2333
**如下:
#include
#include
#include
using namespace std;
const int maxn=100005;
int n,m,root,tt,tot,lnk[maxn],son[2
*maxn],nxt[2
*maxn],a[maxn];
int fa[maxn],top[maxn],siz[maxn],wson[maxn],id[maxn],dep[maxn],rk[maxn];
struct dyttree[4
*maxn];
void add(int
x,int
y)void dfs(int
x,int las)
}void dfs1(int
x,int las)
void buildtree(int
x,int l,int r)
int mid=(l+r)>>1;
buildtree(2
*x,l,mid); buildtree(2
*x+1,mid+1,r);
tree[x].sum=(tree[2
*x].sum+tree[2
*x+1].sum)%tt;
}void pushdown(int
x)void insert(int
x,int l,int r,int z)
int mid=(tree[x].l+tree[x].r)>>1;
if (r<=mid) insert(2
*x,l,r,z);
else
if (l>mid) insert(2
*x+1,l,r,z);
else
tree[x].sum=(tree[2
*x].sum+tree[2
*x+1].sum)%tt;
}int query(int
x,int l,int r)
void put(int
x,int
y,int z)
else
}if(id[x]<=id[y]) insert(1,id[x],id[y],z); else insert(1,id[y],id[x],z);
}int get(int
x,int
y) else
}if(id[x]<=id[y]) ret=(ret+query(1,id[x],id[y]))%tt; else ret=(ret+query(1,id[y],id[x]))%tt;
return ret;
}int main()
tot=0; dfs(root,0); dfs1(root,root); buildtree(1,1,n);
for (int i=1;i<=m;i++)
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為根節點的子...