loj#3046
題意還是很好懂的,問題也很容易轉化為求每個點能到的點的個數之和,最後除以$2$即可
考慮任意一點i能到的點的個數。這些點所組成的點集等於所有包含節點$i$的鏈的點集的並集。
需要哪些資訊才能維護出這個點集?
由於每條鏈都包含了節點$i$,因此這個點集會組成乙個連通塊(暫且這麼叫吧),這個連通塊顯然可以通過確定其邊界上的點確定下來,那麼問題變為如何維護出連通塊的大小
這就是在考察$dfs$序的應用了,先以$dfs$序建立線段樹。借助於虛樹的思想,我們維護出每乙個區間內選擇了點到$1$號節點的根綴的並集大小,記為$siz$。假設現在我們已知線段樹中乙個區間的左區間資訊與右區間資訊,如何得出這個區間的資訊?直接把左右區間的$siz$相加顯然不對,有重複的部分,重複部分的大小是多少?結合$dfs$序,可以發現重合部分就是左區間選擇的點中$dfs$序最大的點$mx$與右區間選擇的點中$dfs$序最小的點$mn$的$lca$的深度,即$dep[lca(mx, mn)]$,左右區間的$siz$相加再減去這個就是這個就是這個區間的$siz$,而最後的連通塊的大小就是整個序列的$siz$減去$dep[lca(mx, mn)]$,$mx$是整個點集中$dfs$序最大的點,$mn$是$dfs$序最小的點。
為了快速求$lca$可以預處理尤拉序與$rmq$,在$o(1)$內查詢$lca$,資訊更新就是$log$的時間複雜度
我們需要乙個連通塊的邊界,這個邊界顯然是由所有鏈的邊界組成的,因此在樹上差分就可維護出邊界
這是對於乙個點的情況。對於所有的點,因為使用了樹上差分,父親節點需要從兒子節點繼承資訊,於是就需要線段樹合併
總時間複雜度是$o(nlogn)$的
**:
#includeusingview codenamespace
std;
typedef
long
long
ll;const
int maxn = 100005
;inline
intread()
intn, m, root[maxn];
ll ans;
inthead[maxn], tot;
struct
edgee[maxn
<<1
];void addedge(int x, inty);
head[x] =tot;
}int
f[maxn];
int cur, lg[maxn<<1], st[20][maxn<<1], arr[maxn<<1
], dfn[maxn], dep[maxn];
void dfs1(int x, int
fa)}
void
rmq()
for(int j = 1; j <= lg[cur]; ++j)
for(int i = 1; i + (1
<< j) - 1
<= cur; ++i)
}int get_lca(int x, int
y)int
ndnum, tim;
struct
seg_treetr[maxn*64
];void update(int
x)void modify(int x, int l, int r, int p, int
w)
int mid = (l + r) >> 1
;
if(dfn[p] <=mid)
else
update(x);
}int merg(int x, int y, int l, int
r)
int mid = (l + r) >> 1
; tr[x].ls =merg(tr[x].ls, tr[y].ls, l, mid);
tr[x].rs = merg(tr[x].rs, tr[y].rs, mid + 1
, r);
update(x);
returnx;}
void dfs2(int
x)
ans += (ll)tr[root[x]].siz -dep[get_lca(tr[root[x]].mx, tr[root[x]].mn)];
}int
main()
dfs1(
1, 0
); rmq();
for(int i = 1; i <= n; ++i)
root[i] = ++ndnum;
while(m --)
}dfs2(1);
printf(
"%lld\n
", ans >> 1
);
return0;
}
ZJOI2019 語言 解題報告
3個 log 做法比較簡單,但是寫起來還是有點麻煩的。大概就是樹剖把鏈劃分為 log 段,然後任意兩段可以組成乙個矩形,就是個矩形面積並,聽說卡卡就過去了。好像這個可以被優化到兩個 log 算了,估計挺麻煩的。乙個 log 的做法看起來還挺厲害的。考慮欽定某個點算它的貢獻,於是我們要算的是所有經過它...
ZJOI2019賽季回顧
zjoi2019落下了帷幕 儘管成績不盡如人意 但是明天還會繼續 正如一句話所說 不要害怕落日的黑暗,因為明天的太陽還會照常公升起 總排rank35,僅以此文章回顧整個賽季 不算很難的題,大家都ak了,也沒什麼好說的 day2t1很傻的乙個地方判錯了,丟分,然後剩下兩個暴力,總分194 day2t3...
ZJOI2019一輪遊記
期待已久的省選終於開始了233,關於之前的一些內容,在zjoi2019一輪停課刷題記錄都可以找到,這裡不再贅述 zjoi2019,bless all 今天難得有休息,昨晚修仙到挺晚的,但早上還是起的很早的說 下了個艦b玩玩感覺不錯,挺喜歡的,然後又是雀魂 現在銀間能上分但銅間就狂掉233 下午和cx...