emmmm這道題的思路實在是神。。雖然做過然而做過一遍還是做不出來。。
本來還想到了另外一種思路。。。不過寫完調來調去發現這個思路完全是錯的qaq要是這樣把隊友坑了那怎麼行qaq
繼續貼清華爺gconeice的題解。。
顯然,暴力求解的複雜度是無法承受的。
考慮這樣的一種暴力,我們把 z 到根上的點全部打標記,對於 l 到 r 之間的點,向上搜尋到第乙個有標記的點求出它的深度統計答案。觀察到,深度其實就是上面有幾個已標記了的點(包括自身)。所以,我們不妨把 z 到根的路徑上的點全部 +1,對於 l 到 r 之間的點詢問他們到根路徑上的點權和。仔細觀察上面的暴力不難發現,實際上這個操作具有疊加性,且可逆。也就是說我們可以對於 l 到 r 之間的點 i,將 i 到根的路徑上的點全部 +1, 轉而詢問 z 到根的路徑上的點(包括自身)的權值和就是這個詢問的答案。把詢問差分下,也就是用 [1, r] − [1, l − 1] 來計算答案,那麼現在我們就有乙個明顯的解法。從 0 到 n − 1 依次插入點 i,即將 i 到根的路徑上的點全部+1。離線詢問答案即可。我們現在需要乙個資料結構來維護路徑加和路徑求和,顯然樹鏈剖分或lct 均可以完成這個任務。樹鏈剖分的複雜度為 o((n + q)· log n · log n),lct的複雜度為 o((n + q)· log n),均可以完成任務。至此,題目已經被我們完美解決。
#include#include#include#include#include#include#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge *j=h[x];j;j=j->next)
#define eps 1e-8
#define inf 201314
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
#define succ(x) (1next=h[x];h[x]=o++;}
int size[nm],top[nm],top,tot,id[nm],son[nm],f[nm],d[nm];
int n,m,_x,_y,a[nm],b[nm],c[nm],ans[nm],p1,p2,tmp[nm],_tmp[nm];
void dfs1(int x)
size[x]++;
}void dfs2(int x)
struct info
}t[4*nm];
void build(int i,int x,int y)
build(i<<1,x,t);build(i<<1|1,t+1,y);
op=ls+rs;
}void pushdown(int i)
}void mod(int i,int x,int y)dep[lca(i,z)]。
(即,求在[l,r]區間內的每個節點i與z的最近公共祖先的深度之和)
第一行2個整數n q。
接下來n-1行,分別表示點1到點n-1的父節點編號。
接下來q行,每行3個整數l r z。
輸出q行,每行表示乙個詢問的答案。每個答案對201314取模輸出
5 2001
11 4 3
1 4 285
共5組資料,n與q的規模分別為10000,20000,30000,40000,50000。
資料已加強 by saffah [
submit][
status][
discuss]
BZOJ 3626 離線 樹鏈剖分 線段樹
思路 抄一波yousiki的 顯然,暴力求解的複雜度是無法承受的。考慮這樣的一種暴力,我們把 z 到根上的點全部打標記,對於 l 到 r 之間的點,向上搜尋到第乙個有標記的點求出它的深度統計答案。觀察到,深度其實就是上面有幾個已標記了的點 包括自身 所以,我們不妨把 z 到根的路徑上的點全部 1,對...
樹剖想法題 BZOJ3626
本來是打算作為樹剖練習的最後一題的,結果一直wa。本來以為是自己寫的太醜。最後發現5w的資料 我開了10w的陣列 然而有乙個陣列要 2 哦,好棒棒。1 include2 include3 include4 include5 define foru i,x,y for ll i x i y i 6us...
bzoj 3626 LCA(樹鏈剖分)
傳送門biu 考慮求lca x,y 的深度,可以把 x 到根路徑上的所有節點權值加一,再查詢 y到根路徑上的所有節點的權值和即為lc a x,y 的深度。將詢問離線,把詢問 r i ld eplc a i,z 拆成兩個詢問 r i 1d eplc a i,z 減去 l 1i 1dep lca i,z...