OI題目類型總結整理


本蒟蒻的小整理qwq~~持續更新(咕咕咕)


數據結構

數據結構 知識點梳理

數據結構——線段樹

推薦yyb dalao的總結——戳我
以后維護線段樹還是把l,r寫到struct里面吧,也別寫len了,調試不好調qwq
初始化和葉節點初始化不太一樣qwq,有的需要統一初始化的就一定注意不要寫到if(l==r)里面qwq

  • 求區間最大子段和 例題:codevs動態最大子段和
    維護區間和,區間前綴最大子段和,區間后綴最大子段和,區間最大子段和。然后合並。(注意這種跨左右子樹還有可能會有貢獻的線段樹寫法上和普通的線段樹不同!)、
  • 求區間最大連續子段(比如說求一個區間內最長0子段的個數) 例題:SHOI腦洞治療儀
    維護區間前綴最大,后綴最大。然后合並即可。需要注意的一點是下面代碼里面的取min(也就是帶詢問的區間更改一定要注意!前后綴長度是不能超過這個長度的):
if(rr<=mid) return query(ls(x),ll,rr);
    else if(mid<ll) return query(rs(x),ll,rr);
    else
    {
        int cur1=query(ls(x),ll,mid);
        int cur2=query(rs(x),mid+1,rr);
        int z1=min(t[ls(x)].maxr,mid-le[x]+1);
        int z2=min(t[rs(x)].maxl,ri[x]-mid);
        return max(max(cur1,cur2),z1+z2);
    }
    
  • 線段樹模擬網絡流 例題:codeforces280div.1D
    這是個神仙啊!!!主要目的是為了優化時間復雜度,就是考慮最大費用流怎么跑的,我們用區間反轉模擬退流過程即可。具體實現請看博文題解。時間復雜度\(O(klogn)\)
  • 一條鏈,兩點之間有給出的距離,要求logn的時間復雜度內,求出一段區間中\(\sum\)任意兩點之間的距離和。例題:HAOI高速公路
    \(ans=\sum_{i=l}^r a[i]*(i-l+1)*(r-i+1)\)
    \(ans=\sum_{i=l}^r a[i]*(-i^2+(r+l)i+(r-l+1-rl))\)
    線段樹維護即可
  • 求歷史最值(線段樹模板3) 例題:CPU監控
    將操作轉換成(a,b),表示最終結果為min(x+a,b)。
  • \(O(logn)\)時間復雜度求最長上升子序列的個數 例題:BZOJ樓房重建
  • 在N個區間中選K個,使得它們的區間交至少為1,求最長區間長度-最短區間長度的最小值。 例題:NOI區間
    先按長短排序,再按尺取法,不足K個的時候就加入到線段樹中,如果滿了就彈出前面的。
  • 一棵樹,每個節點都有顏色,有權值。支持對權值的更改,求樹上某兩個節點之間,擁有某一種顏色的節點的權值的最值或和。 例題:SDOI旅行
    樹鏈剖分,動態開點,給每一個顏色都建立一棵線段樹。
  • 將一個長度為n的序列分為k段,使得總價值最大。一段區間的價值表示為區間內不同數字的個數。\(n<=35000,k<=50\) 例題:CF833B
    轉移方程——\(f[i][j]=max(f[k][j-1]+Calc(k+1,i))\),然后線段樹維護。
  • 一張圖分為兩部分,左右都有n個節點,\(Ai->Ai+1\)連邊,Bi->Bi+1連邊,容量給出
    有m對\(Ai->Bj\)有邊,容量給出。兩種操作
    1.修改某條Ai->Ai+1的邊的容量
    2.詢問從A1到Bn的最大流
    \(n,m<=100000\),流量\(<=10^9\)
    線段樹模擬網絡流,轉化成最小割——\(Ans=A_iA_{i+1}+B_j+B_{j+1}+A_xB_y(x<=i,y>j)\)。A如何更改不會影響到B一方的最小割選擇,所以我們掃一遍A,在B中插入相應的值就行了。
  • 兩種操作,一種是令一個區間升序排列,一種是降序排列,求最后第K位上的數字。 例題:TJOI排序
    二分這個值,然后比他大的置為1,其他的置為0,然后用線段樹維護操作,看最后那個數是1還是0.
  • 兩種操作,一種區間開方,一種區間加。(數值不超過1e5) 例題:UOJ基礎數據結構練習題
    區間開方轉換成區間減維護。
  • 區間開方
    暴力即可
  • 維護一個區間,兩個操作
    1.將區間\([l,r]\)所有數變為\(C^{ai}\)
    2.求區間\([l,r]\)\(\mod p\)的和
    例題:六省聯考 相逢是問候
    我們根據歐拉定理,知道反復進行若干遍操作之后,答案不會再變,所以提前預處理出所有的φ值。同時記錄區間最少的操作次數,如果最小操作次數達到了上限,直接return。
  • 給你一個數列,兩個操作
    1.給一段區間加上一個等差數列
    2.將一段區間分解為最少個數的等差數列,輸出等差數列的個數
    例題:BZOJ1558等差數列
    我們考慮對數列做差,這樣如果是等差數列,那么值應該相等。我們設\(s[0],s[1],s[2],s[3]\)分別表示當前區間中,不考慮兩端、不考慮左端點、不考慮右端點、兩端都考慮,形成等差數列的個數。
  • 扇形面積並,求被至少K個扇形覆蓋的范圍 例題:SHOI2013扇形面積並
    轉換成矩形,用線段樹維護即可。

數據結構——線段樹——線段樹合並

一般線段樹都是權值線段樹,我們對權值線段樹進行合並。

數據結構——線段樹——李超線段樹

放上自己的小整理

數據結構——主席樹(可持久化線段樹)

  • 靜態區間第K大 模板
  • 帶修區間第K大 例題:BZOJ1901
    樹狀數組套主席樹,主席樹不需要繼承歷史版本,它的前綴和用樹狀數組維護了。
  • 鏈上第K大 例題:BZOJ2588
    平常的主席樹是利用前綴和然后做差,現在放到樹上就是樹上差分。但是繼承的時候注意要把繼承上一個節點變成繼承父親的。然后用樹上點差分即可。

數據結構——樹鏈剖分

  • 維護鏈上有向信息,如有向最大差 例題:TJOI2015旅游
    就是維護前綴最大差,后綴最大差以滿足有向的限制。最大差有兩種選擇方式。
  • 如果有節點修改,修改過的節點隨着操作次數增加依然增加,然后求兩個點之間小於等於K的節點個數。 例題:SCOI情報傳遞
    套主席樹,但是操作過程中進行主席樹上修改顯然沒有剛開始就離線處理得好。
  • 每個節點都有一個顏色,求兩點之間不同顏色段數(比如說11122113就是四段)
    額外記錄一個該區間最左端和最右端的顏色即可。
    (如果不是節點有顏色,是邊有顏色呢?)

數據結構——LCT

改變樹的結構,記得要push_up。查詢的時候一定要先push_down。

  • 維護鏈信息(LCT上的平衡樹操作)
  • 動態維護連通性&雙聯通分量
    • 如果是動態加邊,用並查集維護會比findroot更快qwqwq
    • 一定要注意有沒有環出現!!!
  • 維護邊權(常用於維護生成樹)
  • 維護子樹信息
  • 維護樹上染色聯通塊

數據結構——平衡樹

  • 為了讓序列連續,我們可以將一般的splay插入的極小值(-2147483647)變成1,極大值(2147483647)變成n+2.
  • 當一個數可能會對應很多意義(比如說人名?)就不要合並到一個節點里面了,分開建節點!

數據結構——左偏樹

  • 合並,求最值 例題:APIO2012派遣
  • 維護子樹信息(和其他樹一樣,維護add,mul標記,有push_down) 例題:JSOI城池攻占

數據結構——莫隊

數據結構——莫隊——普通莫隊

一般都是對於計算出來區間[l,r]的值之后,能在O(1)或者差不多的時間中快速計算出\([l+1,r],[l-1,r],[l,r-1],[l,r+1]\)的問題。

  • 給定一個序列,詢問一個區間內不同數字的個數。

數據結構——莫隊——帶修莫隊

先離線所有的操作,然后標記上修改的時間戳,還按照普通莫隊做。如果當前處理的詢問在上一個處理的時間之前,就還原之前的所有操作,如果在之后,就先進行之后的所有操作。


數學

數學 知識點梳理

數學——裴蜀定理

  • \(\begin{cases}(n+m)a+(p+q)b=x\\(p-q)a+(n-m)b=y\end{cases}\)
    n,m,p,q為未知解,求是否存在整數解?例題:HAOI向量
    注意還需要進一步分類討論n+m,n-m,p+q,p-q的奇偶性。

數學——歐拉定理(拓展歐拉定理)

  • 給定n,每次使n等於φ(n),求最少幾次操作后n=1。 例題:HAOI外星人
    求出有多少個數作為因子即可。

數學——莫比烏斯反演

  • \(gcd(i,j)=k,i\in[a,b],j\in[c,d]\)的個數 要求\(O(N)\)
  • \(\sum_{i=1}^n\sum_{j=1}^md(ij)\) 要求\(O(N\sqrt N)\)

數學——莫比烏斯反演——公式與技巧

  • \(i\in[1,n],j\in[1,m]\;then\;d(ij)=\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=1]\)
  • \(\sum_{i=1}^n\lfloor\frac{m}{k}\rfloor[x|gcd(i,j)]=\sum_{i=1}^{\lfloor\frac{n}{x}\rfloor}\lfloor\frac{m}{xk}\rfloor\)
  • \(\sum_{i=1}^{n}\lfloor\frac{n}{i}\rfloor\)——整除分塊

數學——BSGS

  • 一般用來在\(\sqrt N\)的時間內,解決對於\(y^x\equiv z\pmod p\),給定\(y,z,p\)求x的問題。

數學——矩陣樹定理

注意不合法的情況不需要給它賦id,直接跳過即可。

數學——容斥

ans=至多有n個-至多有n-1個+至多有n-2個......(奇加偶減)

  • 求一個區間內(范圍1e10)只包含數x,以及這些只包含數x的數的倍數的個數。 例題:SCOI2010幸運數字
    先處理出來只包含數x的數都有哪些。lcm(i)表示是其中i個數的lcm。
    ans=lcm(1)-lcm(2)+lcm(3)......
  • 給定一個序列,每次只能刪除一個數,刪除到這個數列非降為止,問一共有多少種刪法? 例題:BZOJ4361 isn
  • 有障礙的網格圖計數
    對於一個確定的點(x,y),走到它的路徑條數為\(C_{x+y}^x\)
    遞推公式——\(dp[i]=C_{x[i]+y[i]}^{x[i]}-\sum_{j=1}^{i-1}dp[j]\times C_{x[i]-x[j]+y[i]-y[j]}^{x[i]-y[i]}\)

對於n個條件,一個都不滿足的sum=sum(隨便放/總數)-sum(至少滿足其中1個條件)+sum(至少滿足其中2個條件)-sum(至少滿足其中3個條件)......

lucas定理

  • \(O(n\sqrt n)\)的時間中快速計算\(f[n][k]=\sum_{i=0}^kC_n^i\pmod {2333}\)
    \(=C_{n/p}^0\times \sum_{i=0}^{p-1}C_{n\%p}^i+C_{n/p}^1\times \sum_{i=0}^{p-1}C_{n\%p}^i+...+C_{n/p}^{k/p-1}\times \sum_{i=0}^{p-1}C_{n\%p}^i+C_{n/p}^{k/p}\times \sum_{i=0}^{k\%p}C_{n\%p}^i\)
    \(=\sum_{i=0}^{p-1}C_{n\%p}^i\times(C_{n/p}^0+C_{n/p}^1+...+C_{n/p}^{k/p-1})+\sum_{i=0}^{k\%p}C_{n\%p}^i\)
    \(=\sum_{i=0}^{p-1}C_{n\%p}^i\times \sum_{j=1}^{k/p-1}C_{n/p}^j+\sum_{i=0}^{k\%p}C_{n\%p}^i\)
    \(=f[n\%p][p-1]\times f[n/p][k/p-1]+C_{n/p}^{k/p}\times f[n\%p][k\%p]\)

圖論

圖論 知識點梳理
樹上問題 知識點梳理
網絡流 知識點梳理

圖論——生成樹

圖論——生成樹——kruskal生成樹

例題:NOI2018歸程\(\;\)peaks加強版

  • 對於一個圖,執行有關於從某個點出發的第幾條小/大的邊,或者從某個點出發小於/大於x的邊不計算相關問題,強制在線。

圖論——歐拉回路

  • 給出一個有向圖,問至少刪掉多少條邊使得這個圖有歐拉回路。
    \(p_i=in[i]-out[i]\),如果\(p_i\),從S連向i,否則i連向T,容量為\(|p_i|\)。然后一條有向邊\((u,v)\),網絡劉忠

圖論——基環樹

對於一個n點n邊的圖,如果途中只存在一個環,則稱之位基環樹。細分則有基環樹,基環內向樹,基環外向樹。
一般解決方法都是樹形DP,然后對環部分進行環形DP。不然可以考慮斷環法。

  • 例題:NOIP2018旅游
  • 例題:ZJOI2008騎士
  • 例題:IOI2008island

圖論——分層圖

  • 在一張圖上移動,但是在相同的坐標位置因為其他一些條件的約束,有不同的狀態。

圖論——網絡流

圖論——網絡流——最大流

  • 常用建圖模型1:對於一個點多種狀態的(比如說在不同時刻狀態意義不一樣),可以把這個點拆成n個點,來分別表示不同時刻的狀態。
  • 詢問最大流的幾種方案中最長邊的最小值 例題:SDOI費用流
    二分+限流跑dinic
  • \(n \times m\) 的矩陣中取出 n 個不同行且不同列的數,求取出的 n 個數中第 k 大的最小值。 例題:SCOI2015 小凸玩矩陣
    轉換求最大數的最小值,二分一個值,只要有n-k+1個數小於等於它即可。考慮網絡流求最大匹配。S向行連邊,列向T連邊,如果某個數字小於等於二分的值,將它的行列連邊。

圖論——網絡流——最小割

一般都是最優化問題的決策問題的解決利器。很多題目利用總點權(或者說所有正權點的和)-最小割來解決問題。qwqwq

  • 最大權閉合子圖模型
    • 出現環怎么辦。縮點,給每個強連通分量里面的點都連一條-inf的邊到T。(NOI植物大戰僵屍)
  • 切糕模型 (給定一個立方體,它被分成pqr個格子,每個格子中都有一個數字,相鄰地選擇數字,每一行每一列都要選擇一個數字。要求這些數字和最小。)
    • 建r+1層,然后這些邊的權值是對應位置的數字權值。從每一個點(第z層)向它旁邊四個縱軸連一條指向第z-d層的有向邊
  • 帶組合的決策問題 (給定n個點,每個點放進集合A有收獲,放進B有對應收獲,一些點組合起來一起放進A或B有額外收獲,問最大收獲?)
    • 如果處理額外收獲?最小割,割掉表示不選。每個組合建對應集合個的新點,新點連對應集合的點INF。如果是問最小收獲?直接把取值反成n-ci按原來的求,之后答案再還原一下即可。
  • 方格中有節點,每一個節點和周圍的一些點不能共存,現在計算最多可以選出多少個節點。
    權值為1的最大點權獨立集——總權值-最小割。
  • 平面圖最小割=對偶圖最短路(降低復雜度)

圖論——網絡流——費用流

  • 一張圖,起點是1,終點是n,問起點到終點再從終點到起點,每個點只能被訪問至多一次,問一來一回最多能經過多少節點。 例題:航空路線問題
    一來一回==從起點出發兩次。最大費用流,拆點,中間流量為1,費用為0,強制u+n向v連邊。但是要注意的是,有可能最佳方案是從1到n然后再到1,所以不能對於每條可行的線路的容量設置為1,因為這樣的話就再也無法回來了qwq。
  • 早上訂貨,可以定很多,每天早上的每單位的貨有一個可能不同價格。每天必須保證至少x的供應量,貨可以囤積到之后的天,但是量不能超過s,而且每單位需要支付一定的價錢p。
    裂點,分成早晚兩個。S向早上連容量INF的邊,早上向T連容量為供應量,費用為0的邊。早上向晚上連容量s的邊,晚上向次日早上連容量s,費用為p的邊。最小費用最大流。
  • 如果是一條邊只能取一次,就連一條容量為1,費用為收益的邊,再連一條容量INF,費用為0的邊。
  • 如果是一條邊的費用為諸如容量\(^2\times\)收益的這種不好計算的,考慮拆邊,統一容量為1。

注意網絡流一定不要因為數組開小而GG!!一定一定要注意邊的數量,開夠數組!!!

圖論——其他


動態規划

動態規划——背包

動態規划——樹形DP

  • 每一個數都有一個父親,必須自己的父親先安裝才能安裝自己。每一個數安裝都有安裝所需空間和獲得效益,現在給定最大可用空間,求最大效益。例題:HAOI2010 軟件安裝
    可能成環,要么全裝要么一個不裝,所以先tarjan縮點,注意縮點之后把縮得的點連上這個環里面其他點連出去的邊。然后就是一個樹,做樹形DP即可。

動態規划——樹形DP——虛樹優化

  • 保留有效信息(如詢問點和LCA),一般都出現在有詢問點總和的條件約束的題目中。

動態規划——區間DP

  • 給定一個序列,可以刪除大於1長度的,連續的,形成等差數列的數,刪完之后兩邊拼合,求最后最少能剩下多少個數?
    無論怎么刪,總是能拆成刪若干次兩個的+若干次三個的。所以區間DP+分類討論即可。
  • n個數,對於每一個數i,有ai個數比它大,有bi個數比它小,可能有相同數出現。問最小的不合法約束數量? 例題:HAOI problem a
    做一個轉化,每一個數的約束條件都是一個區間,這個區間內他們的數值都相同。每個區間都有一個權值,然后線性地DP即可。不過注意一個區間內最多有min(對應區間為此的數的數量,r-l+1)。

動態規划——區間DP——有決策點的DP

  • 已知[1,x]區間里有東西,每次可以從[1,n]區間中以a[i]的代價詢問該點是否有東西,求最壞情況下能確定x所需要的代價? 例題:挖油,要求\(O(N^2)\)
    區間DP+優化。主要是用優先對列將其從\(O(n^3)\)優化到\(O(n^2)\),用n+1個優先隊列維護該點狀態主要從哪一種(作為最壞的)轉移而來,1個維護固定左端點的,每次更換枚舉的i時清空。n個維護固定右端點的,無需清空。

動態規划——DP套DP

某些DP問題的子問題不能簡單地解決,而必須用另一個DP解決的問題。
即:外面的DP的狀態是存的里面的DP各個狀態的值,利用里層的狀態來判斷外層的DP是否合法,類似的問題有LCS為定值的序列的方案數等等。

-例題:hero and devil

動態規划——DP優化——單調隊列

動態規划——DP優化——單調棧

動態規划——DP優化——矩陣加速

動態規划——DP優化——決策單調性

動態規划——AC自動機上DP

其實可以把AC自動機看作一個DAG,所以這個也就是DAG上的DP問題了。

  • 給定一個數n,以及一些模式串比如說“123”(都沒有前導零)。問從1到n的數中有多少個數的十進制表示中沒有出現任何子串為給定模式串?\(n\le10^{10^{18}},m\le10\)
    AC自動機上DP+矩陣快速冪優化遞推
  • 上一個問題,有前導零。\(n\le2e5,m\le 200\) 例題:SDOI數數
    分成一類為沒有長度限制的(即長度在n的長度以內的),一類為長度正好為n的,然后又分兩種,一種是當前位已經達到限制,一種是還未達到限制。遞推轉移即可。

動態規划——其他

  • 快速約瑟夫環
    我們知道約瑟夫問題的通式一般都是這個樣子的——\(dp[i]=(dp[i-1]+k)\mod i\),時間復雜度是\(O(n)\)的。但是如果我們想要\(O(logn)\)的做法呢?如果\(f[i-1]+k\)不超過i的時候,我們可以一次多加幾個。
  • 一個n*m的矩陣,可以選擇其中一個數字進行修改(當然也可以不修改),求最大/最小矩陣和。
    記錄行/列最小值/最大值方便替換,記錄一個不修改的最大/最小矩陣和和一個帶修改的最大/最小矩陣和。
  • 一個n*m的矩陣,可以選擇其中一個數字進行修改(當然也可以不修改),使得矩陣的最大子矩陣盡可能小。
    DP+分類討論
  • 最長公共子序列的長度和最長公共子序列的個數。 例題:HAOI2010最長公共子序列
    長度很好做.\(len[i][j]=max(len[i-1][j],len[i][j-1])\)\(if(a[i]==b[j]) len[i][j]=len[i-1][j-1]+1\)
    個數則\(sum[i][j]+=sum[i][j-1]+sum[i-1][j]\)
    \(if(len[i-1][j-1])+1==len[i][j]\) \(then\;sum[i][j]+=sum[i-1][j-1]\)
    \(if(len[i-1][j-1]==len[i][j]\) \(then\;sum[i][j]-=sum[i-1][j-1]\)
  • 坐座位,每個人都有一個編號,大家按照次序進入,從自己的編號開始做,如果位置被占了就順次向后移動,直到找到一個空座位為止。事先有些人的為止已經預定過了不能更改。現在要給沒有預定座位的人賦編號,問有多少種方案? 例題:HAOI problem c
    顯然編號確定了之后,坐座位的序列就是唯一的了,所以我們要給不同的人安排編號來使得方案不同。
    \(dp[i][j]\)表示第i個人之后,除去那預先預定過座位的人,我們給j個人制定了座位。\(dp[i][j]=dp[i+1][j-k]*C_j^k\),時間復雜度\(O(n^3)\)
  • 最短路上DAG計數(這里指經過邊的計數) 例題:HAOI道路
  • 先拓撲排序,然后按照次序正着DP一次,反着DP一次,乘起來即可。

字符串

字符串——哈希

字符串——KMP

字符串——manacher

字符串——AC自動機

一般AC自動機是解決字符串匹配一類的問題。

  • 求一些模式串(不重復)有沒有在文本串中出現過
  • 求一些模式串(不重復)在文本串中出現多少次?最多的是哪個串?
  • 求一些模式串(有重復)在文本串中出現多少次?例題:TJOI單詞 \(n\le200\),模式串總長度\(\le1e6\)
    暴力跳fail肯定會T,所以我們按dfs序從后往前遍歷,往自己的fail邊指向的節點累加答案。
  • 求有沒有可能存在一個無限長的串,使得其中不包含給定的一些文本串——也就是說不存在一個串,無法匹配給定的這些文本串。
    盡可能讓模式串匹配。有fail指針就要往上面跳。可以證明如果存在這樣一個串,那么加上fail邊,AC自動機上一定會出現一個環。

字符串——SA后綴數組

字符串——SAM后綴自動機

后綴自動機一般都用於解決什么樣的問題呢?

  • 求一個子串不同子串的數量。
    也就是\(\sum longest-shortest+1=\sum longest-parent.longest\)
  • 求兩個字符串的最長公共子串。

計算幾何

計算幾何——凸包

計算幾何——動態凸包

  • 例題:HAOI防線修建

計算幾何——最小圓覆蓋


其他技巧

  • 曼哈頓距離小於等於d的菱形可以通過更改坐標系(旋轉45度)使其變成矩形。例題:BZOJ極光
  • 求滿足\(l_i\le L\)或者\(R\le r_i\)\(i\)的數量,可以轉化為以\(L,R\)為原點,求坐標在第二象限的點的個數,可以用線段樹掃描線來做。 例題:ARC exhausted?
  • 異或——異或一個數兩次,就相當於沒有對這個數進行操作。對於一個區間[l,r],我們設a[i]為前i個數的異或和,顯然對於區間[l,r],a[l-1]^a[r]就是這個區間里面所有數的異或和。
  • 二分,一般都是用來轉化成判定性問題來簡化問題的,或者出現“最大值最小”,“最小值最大”之類的字眼。
  • 對於一個數x,區間[A,B]內它的倍數是⌊Bx⌋+⌈Ax⌉+1
  • 環上問題一般都是斷環為鏈,復制兩倍
  • 鏈上一個接一個的轉移顯然可以用倍增優化
  • 尺取法(維護兩個指針,以\(O(n)\)時間復雜度解決一類單調性問題)

--

一些讀題上的問題

  • 注意一些“請問在字符串A中字符串B出現了多少次,這些出現的位置只要有任何一個不一樣就行了,所以用.find的時候pos+1而不是pos+length(B)
  • 問第K大,就真的是從大到小第K個數!!


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM