-> 戳這裡檢視題面
julao口中的樹上帶修莫隊的板子題
這個題拆開來說就是:帶修莫隊+樹上莫隊
帶修莫隊是莫隊的最基本的一種,就是將詢問排序後,按時間戳將修改操作增加或減少
樹上莫隊有兩種寫法,分別是按照大小分塊和按照尤拉序分塊,這裡介紹用尤拉序分塊的寫法,通過尤拉序我們可以將樹上問題轉化為序列問題,因為尤拉序裡兩個相同的數之間包含ta的子樹
tip:對於樹上莫隊的尤拉序寫法還需要特別注意一下lca的特判,當lca
(x,y
)≠x∣
ylca(x,y)\ne x|y
lca(x,
y)
=x∣y
時,在尤拉序上是不會出現lca
lcalc
a的,需要專門計算
#include
using
namespace std;
namespace zzc
e[maxn<<1]
;struct chan
c[maxn]
;struct que
q[maxn]
;bool
cmp1
(que a,que b)
bool
cmp2
(que a,que b)
void
add(ll u,ll v)
ll idx;
void
dfs(ll u,ll ff)
id[++idx]
=u; out[u]
=idx;
}void
getpre()
}}ll lca
(ll x,ll y)}if
(x==y)
return x;
for(
int i=
20;i>=
0;i--)}
return fa[x][0
];}void
calc
(int pos)
void
update
(int pos,
int col)
else c[pos]
=col;
}void
work()
for(ll i=
1;i<=n;i++
)scanf
("%lld"
,&c[i]
),pre[i]
=c[i]
;dfs(1
,0);
getpre()
;for
(int i=
1;i<=idx;i++
)for
(ll i=
1;i<=q;i++
)else
}sort
(q+1
,q+qcnt+
1,cmp1)
; tim=0;
ll l=
1,r=0;
for(
int i=
1;i<=qcnt;i++
)while
(tim>q[i]
.ti)
while
(r.r)calc
(id[
++r]);
while
(l>q[i]
.l)calc
(id[
--l]);
while
(l.l)calc
(id[l++])
;while
(r>q[i]
.r)calc
(id[r--])
; ll x=id[l]
,y=id[r]
,tmp=
lca(x,y);if
(tmp!=x&&tmp!=y)
else q[i]
.val=ans;
}sort
(q+1
,q+qcnt+
1,cmp2)
;for
(int i=
1;i<=qcnt;i++)}
}int
main()
P4074 WC2013 糖果公園
tag 樹上帶修莫隊 題意 樹上每個點有一種糖果,求 sum c sum v c w i 其中c為糖果種類,cnt c 其為出現次數。離線樹上帶修莫隊。先進行樹上分塊。分塊內的詢問按照出發點 終止點 詢問id優先順序依次遞減排序。對於樹上莫隊,其實就是在尤拉序上莫隊。因為尤拉序的性質,即每個節點子樹...
題解 洛谷 P4074 WC2013 糖果公園
p4074 wc2013 糖果公園 給你一棵樹樹,點有點權,帶修改,每一次經過一種點權會有不同的貢獻 隨著經過次數再變 問你從乙個點到乙個點的貢獻和 樹上帶修莫隊。用 cnt i 表示 i 這個點的權值的出現次數。用 a i 表示 i 號點的權值。用 v i 表示一權值 i 的貢獻定值。用 v i ...
P4074 WC2013 糖果公園 樹上帶修莫隊
戳這裡檢視題面 julao口中的樹上帶修莫隊的板子題 這個題拆開來說就是 帶修莫隊 樹上莫隊 帶修莫隊是莫隊的最基本的一種,就是將詢問排序後,按時間戳將修改操作增加或減少 樹上莫隊有兩種寫法,分別是按照大小分塊和按照尤拉序分塊,這裡介紹用尤拉序分塊的寫法,通過尤拉序我們可以將樹上問題轉化為序列問題,...