MOI 集訓 Week 2——根號分治

· · 算法·理论

這是澳門信息學代表隊集訓講課的課件,只提供 Sol 而不提供思考過程的解析。

建議先自己思考,再觀看題解,所以所有的 Sol 默認是收起來的。

Part I 數據結構詆毀者

這一部分的內容不需要你掌握一些複雜的數據結構。

P3396 哈希冲突

嘗試思考暴力做法,思考一下,什麼情況下你的做法會比較快?什麼情況下你的做法會比較慢?

::::info[Solution]

$x\leq \sqrt n$ 時我們分出來的不同的類別是很少的,一個位置對應的類別只有 $\sqrt n$ 個,修改時可以暴力改。 所以把查詢分類,不同規模用不同做法。 :::: ### 練習題: - [P9809 [SHOI2006] 作业 Homework。](https://www.luogu.com.cn/problem/P9809) - [P1483 序列变换。](https://www.luogu.com.cn/problem/P1483) - [CF1921F Sum of Progression。](https://www.luogu.com.cn/problem/CF1921F) - [P3591 [POI 2015 R3] 访问 Visits。](https://www.luogu.com.cn/problem/P3591) ## [P2425 小红帽的回文数](https://www.luogu.com.cn/problem/P2425) 我們發現這個問題無法迴避枚舉進制。 意識到自己的無能,往往是通往理性和成功的第一步。 ::::info[Solution] 由於求進制是 $\mathcal O(\log n)$ 級別的,我們直覺上可以對於 $2\sim 10^5$ 的進制暴力判定。 否則進制數長度最多為 $2$,存在簡單做法。 :::: ## [P8572 [JRKSJ R6] Eltaw](https://www.luogu.com.cn/problem/P8572) 注意到 $n$ 和 $k$ 都可能會很大,但是 $nk\leq 5\times 10^5$。 ::::info[Solution] 這啟發我們:$n$ 和 $k$ 不會同時大。 - 當 $k\leq 1000$ 考慮前綴和加暴力。 - 當 $n\leq 1000$ 考慮枚舉所有行中的區間預處理答案。 :::: ## [CF1806E Tree Master](https://www.luogu.com.cn/problem/CF1806E) 意識到自己的無能,往往是通往理性和成功的第一步。 ::::info[Solution] 直接記憶化搜索即可。 證明是,我們把樹的每一層按照包含的點數分類: - 對於點數大於 $\sqrt n$ 的層,這樣的層只有最多 $\sqrt n$ 個,而詢問每次只會進過一層一次,所以這一部分時間複雜度為 $\mathcal O(q\sqrt n)$。 - 對於點數小於 $\sqrt n$ 的層,設點數為 $x$,這一層有效的訪問最多只有 $x^2$ 次,用簡單的不等式知識知道把 $n$ 劃分成許多個 $x(x\leq \sqrt n)$,$x^2$ 總和的最大值是 $\mathcal O(n\sqrt n)$ 級別的。 :::: ## [P2261 [CQOI2007] 余数求和](https://www.luogu.com.cn/problem/P2261) 模數一直在變化,我們知道這種情況下模是沒有什麼性質的。意識到自己的無能,往往是通往理性和成功的第一步。 因此第一步必然是轉換為整除形式。 $$ \sum_{i=1}^n k\bmod i=\sum_{i=1}^nk-i\lfloor \frac n i \rfloor=nk-\sum_{i=1}^ni\lfloor \frac n i \rfloor $$ ::::info[Solution] 離散函數 $f(x)=\lfloor \frac n x \rfloor$ 的圖像如下: ![](https://cdn.luogu.com.cn/upload/image_hosting/x5llx2gp.png) 我們可以證明 $f(x)$ 的取值種類的不嚴格上界為 $2\sqrt n$: - 對於 $x\leq \sqrt n$,種類上界為 $\sqrt n$ 種。 - 對於 $\sqrt n<x$,$f(x)$ 的取值範圍在 $[1,\sqrt n]$ 範圍內,因此種類上界也是 $\sqrt n$。 顯然每種取值對應的 $x$ 區間是連續的,區間內部我們求解一個等差數列求和即可。 :::: 整除分塊往往需要結合一些較難的數論知識,比如莫比烏斯反演,在這裡我們不多贅述,亦不提供練習題。 如果你希望對這個 Trick 有更加深入的理解,可以觀看我的遠古博客:[浅谈整除分块](https://www.cnblogs.com/dengduck/p/17382929.html)。 # Part II 圖論的誘惑 在圖的問題中經常會出現和度數相關的時間複雜度,這類題目很多都可以根號分治。 假如總邊數為 $m$,那麼顯然度數大於 $\sqrt m$ 的點最多只有 $\sqrt m$ 個,我們不妨記這些點為**重點**,其餘點為**輕點**。 以下三道題目我們將可以看到這種思想的運用。 ## [ [ABC219G] Propagation](https://www.luogu.com.cn/problem/AT_abc219_g) 我們對於每次操作的流程應該是很明確的:獲得點值——修改其他點。這對做法沒有直接啟發,但你可以想得清晰一些。 ::::info[Solution] 輕點有簡單而暴力的做法,那麼我們思考重點怎麼做。 難點大概是我們修改其他點的時候,需要修改的點太多,我們想到可以類似線段樹懶標記的做法——既然我找別人很麻煩,那別人找我不就行了? 我們在點上記錄一下有一個整體操作,然後所有的點在獲得點值的時候要去相鄰的所有重點“領取”這個標記。由於標記可能不唯一,所以我們要記錄標記的產生時間,選擇最新的標記即可。 :::: ## [P1989 【模板】无向图三元环计数](https://www.luogu.com.cn/problem/P1989) 我們知道統計無論如何至少要枚舉一條邊。枚舉一個點肯定無法統計。意識到自己的無能,往往是通往理性和成功的第一步。 這裡有一個特別關鍵的轉化,如果你完全沒有頭緒可以點開這條錦囊妙計。 ::::info[錦囊妙計] 如果我們把無向圖轉換為有向圖,是否可以使得一些點的出度或者入度控制在某一上界內呢? :::: ::::info[Solution] 如果我們欽定邊為有向邊,方向為度數小的點指向度數大的點: - 輕點的度數本身就小於 $\sqrt m$。 - 重點只能指向重點,度數無法超過 $\sqrt m$。 我們直接枚舉 $a\to b\to c$ 再判定是否存在邊 $a\to c$,注意到 $a\to b$ 的時間複雜度應該是 $b$ 的度數,所以為 $\mathcal O(\sqrt m)$,而 $a\to b$ 顯然只有 $m$ 條,所以總時間複雜度為 $\mathcal O(m\sqrt m)$。 :::: ### 練習題 - [P8250 交友问题。](https://www.luogu.com.cn/problem/P8250) - [P2500 [SDOI2012] 集合。](https://www.luogu.com.cn/problem/P2500) - [P6815 [PA 2009] Cakes。](https://www.luogu.com.cn/problem/P6815) # Part III 數據結構享受者 前置知識:你需要有一定的數據結構基礎(分塊)。 如果你不會分塊,可以嘗試完成前面的練習。因為意識到自己的無能,往往是通往理性和成功的第一步。 ## [P5309 [Ynoi2011] 初始化](https://www.luogu.com.cn/problem/P5309) 根號分治似乎都是全局操作,我怎麼才能知道局部得到的貢獻呢? ::::info[Solution] 對於 $x\geq \sqrt n$ 利用分塊維護單點修改區間查詢。 對於 $x\leq \sqrt{n}$ 每一種 $x$ 維護一種分塊,發現只需要維護前 $x$ 項即可,對於整塊貢獻是容易計算的,對於邊界考慮對於修改求前綴和,後綴和,這樣貢獻可以一起求出來。 時間複雜度 $O(n\sqrt n)$。 :::: ## [P7710 [Ynoi2077] stdmxeypz](https://www.luogu.com.cn/problem/P7710) 這個問題感覺在樹上完成很沒有前途,怎麼辦呢? 進一步地,根號分治似乎都是全局操作,我怎麼才能只對局部修改呢? ::::info[Solution] 首先樹上查詢一定是不好弄的,考慮求出 $\text{DFS}$ 序,數組每一項記錄其深度。 則問題變成在區間 $[dfn_x,dfn_x+sz_x-1]$ 中 $dep_y\equiv dep_x+a\pmod p$ 的 $y$ 項進行修改(注意這裡的 $a,p$ 是將給出的操作轉換得出的)。 注意到根號分治處理線上問題都是整體操作,這裡卻是區間操作,考慮分塊處理,塊長為 $B$,邊界塊暴力修改。 那我們對於每個區塊操作就相當於整體操作了。 思考 $p\leq k$ 的情況,可以直接打標記,$f_{i,j,k}$ 表示第 $i$ 塊模 $j$ 為 $k$ 的值需要加上的值,一共有 $\dfrac n B$ 塊。 $p\geq k$ 的情況我們發現深度的種類很少,考慮直接維護 $g_{i,j}$ 表示深度為 $i$ 的點在第 $j$ 區塊需要加上的值, 注意到直接做區間加要進行 $\dfrac n k$ 次,直接跑肯定寄,而查詢是單點查詢,所以可以用差分。 時間複雜度為 $\mathcal O\left((B+\dfrac n B+K+\dfrac n K)q\right)$,需要調整區塊長和閾值。 ::::