樹鏈剖分+線段樹,備用。
等待補充詳細解釋中。
/*1 x y z x到y最短路徑上加上z
2 x y 求x到y的最短路徑上的節點值之和
3 x z 以x為根節點的子樹內的所有節點值都加上z
4 x 以x為根節點的所有節點值之和
*/#include
void read(int &y)
while(x>='
0'&&x<='9'
)
y*=f;
}struct
edge
e[200005
];int
n,m,s,p,cnt,maxson,tot;
int head[100005
];int dep[100005],fa[100005],siz[100005
];int id[100005],wt[100005],w[100005
];int son[100005],top[100005
];int a[400005],lz[400005
];long
long
res;
void swap(int &a,int &b)
void add(int u,int
v)void dfs1(int x,int f,int
deep)
}}void dfs2(int x,int
topf)
}void build(int o,int l,int
r)
int mid=(l+r)>>1
; build(o
<<1
,l,mid);
build(o
<<1|1,mid+1
,r);
a[o]=(a[o<<1]+a[o<<1|1])%p;
}void putdown(int o,int l,int
r)void query(int ll,int rr,int o,int l,int
r)
if(lz[o]) putdown(o,l,r);
int mid=(l+r)>>1
;
if(ll<=mid) query(ll,rr,o<<1
,l,mid);
if(rr>mid) query(ll,rr,o<<1|1,mid+1
,r);
}void update(int k,int ll,int rr,int o,int l,int
r)
else
}int qy(int x,int
y)
if(dep[x]>dep[y]) swap(x,y);
res=0
; query(id[x],id[y],
1,1,n);
ans+=res;
return ans%p;
}void upy(int x,int y,int
k)
if(dep[x]>dep[y]) swap(x,y);
update(k,id[x],id[y],
1,1,n);
}int qson(int
x)void upd(int x,intk)
intmain()
dfs1(s,
0,1);
dfs2(s,s);
build(
1,1,n);
while(m--)
else
if(op==2
)
else
if(op==3
)
else
}return0;
}
樹鏈剖分 模板
class match node a n struct no no aa n 4 void init void addpage int x,int y void dfs int s,int faa,int h 根節點,父節點和深度的 if max 0 son s sign void dfs2 int...
模板 樹鏈剖分
define maxn 50010 define l u u 1 define r u u 1 1 寫在類裡面爆棧 int n,m,q int tim 時間戳 int num maxn 樹上每個節點的初始值 int siz maxn siz u 表示以u為根的子樹的節點數 int top maxn ...
樹鏈剖分模板
點權模板 1 m a b c將節點a到節點b路徑上所有點都染成顏色c 2 q a b詢問節點a到節點b路徑上的顏色段數量 連續相同顏色被認為是同一段 如 112221 由3段組成 11 222 和 1 const int n 100100 struct edge g n 2 int cnt,head...