LeeShoWdian
      • Sharing URL Link copied
      • /edit
      • View mode
        • Edit mode
        • View mode
        • Book mode
        • Slide mode
        Edit mode View mode Book mode Slide mode
      • Customize slides
      • Note Permission
      • Read
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Write
        • Owners
        • Signed-in users
        • Everyone
        Owners Signed-in users Everyone
      • Engagement control Commenting, Suggest edit, Emoji Reply
    • Invite by email
      Invitee

      This note has no invitees

    • Publish Note

      Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

      Your note will be visible on your profile and discoverable by anyone.
      Your note is now live.
      This note is visible on your profile and discoverable online.
      Everyone on the web can find and read all notes of this public team.
      See published notes
      Unpublish note
      Please check the box to agree to the Community Guidelines.
      View profile
    • Commenting
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
      • Everyone
    • Suggest edit
      Permission
      Disabled Forbidden Owners Signed-in users Everyone
    • Enable
    • Permission
      • Forbidden
      • Owners
      • Signed-in users
    • Emoji Reply
    • Enable
    • Versions and GitHub Sync
    • Note settings
    • Note Insights New
    • Engagement control
    • Make a copy
    • Transfer ownership
    • Delete this note
    • Insert from template
    • Import from
      • Dropbox
      • Google Drive
      • Gist
      • Clipboard
    • Export to
      • Dropbox
      • Google Drive
      • Gist
    • Download
      • Markdown
      • HTML
      • Raw HTML
Menu Note settings Note Insights Versions and GitHub Sync Sharing URL Help
Menu
Options
Engagement control Make a copy Transfer ownership Delete this note
Import from
Dropbox Google Drive Gist Clipboard
Export to
Dropbox Google Drive Gist
Download
Markdown HTML Raw HTML
Back
Sharing URL Link copied
/edit
View mode
  • Edit mode
  • View mode
  • Book mode
  • Slide mode
Edit mode View mode Book mode Slide mode
Customize slides
Note Permission
Read
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Write
Owners
  • Owners
  • Signed-in users
  • Everyone
Owners Signed-in users Everyone
Engagement control Commenting, Suggest edit, Emoji Reply
  • Invite by email
    Invitee

    This note has no invitees

  • Publish Note

    Share your work with the world Congratulations! 🎉 Your note is out in the world Publish Note

    Your note will be visible on your profile and discoverable by anyone.
    Your note is now live.
    This note is visible on your profile and discoverable online.
    Everyone on the web can find and read all notes of this public team.
    See published notes
    Unpublish note
    Please check the box to agree to the Community Guidelines.
    View profile
    Engagement control
    Commenting
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    • Everyone
    Suggest edit
    Permission
    Disabled Forbidden Owners Signed-in users Everyone
    Enable
    Permission
    • Forbidden
    • Owners
    • Signed-in users
    Emoji Reply
    Enable
    Import from Dropbox Google Drive Gist Clipboard
       Owned this note    Owned this note      
    Published Linked with GitHub
    • Any changes
      Be notified of any changes
    • Mention me
      Be notified of mention me
    • Unsubscribe
    --- type: slide --- <style> .reveal .slides { text-align: left; font-size:35px; } </style> ## 分治 Advanced Competitive Programming 2/17 ---- 這堂課不會講技巧,全都是例題講解。 希望大家邊聽邊想,時不時會抽人回答問題。 --- ## 例題:區間和小於t 給一個長度為$n$的序列,有幾個子區間的總和會小於$t$ $1 \leq n \leq 2*10^5$,$\left| t \right| \leq 10^{14}$ ---- 這題雖然有資結作法,但我們這裡用分治的方法想一下 想一下怎麼把小區間的答案轉移到大區間 ![image](https://hackmd.io/_uploads/BydNwwxip.png) ---- 當兩個小區間長這樣,這時候有一段連續的區間和小於$t$ ![image](https://hackmd.io/_uploads/rkENiO75a.png) ---- 不難發現你會用到左區間的後綴和加上右區間前綴和 這個例子為5+11 ![image](https://hackmd.io/_uploads/r1s8FDxoT.png) ---- 可以把左區間的後綴和排序,右區間的每個前綴和用二分搜去找左區間的有幾個後綴和可以相加<$t$ 算出來的答案數量相加為答案 ---- 分治的難點在於要去思考小區間怎麼去計算答案,然後把小區間算答案的方式帶到大區間 接下來用更多例題帶大家思考🐳 --- ## 例題:[太陽軍團(互動題)](https://neoj.sprout.tw/problem/127/) 給你一個不知道長怎樣,很大很大的$N*M$陣列,你可以多次詢問某一格的值是多少,且已知每一列的最大值出現位置都在上一列最大值的右邊,請你找出每一列的最大值出現在哪裡。 $2 \leq N \leq M \leq 10^6$,最多詢問$10^8$次 ![image](https://hackmd.io/_uploads/rJEFyYXca.png =400x) ---- 直接暴力$O(NM)$檢查每個格子顯然是不行的 要怎麼用分治來解這題呢,給大家幾分鐘時間想一下 ---- 我們可以先找中間那排,用一次$O(M)$掃過去,找最大值在哪 ![image](https://hackmd.io/_uploads/Sy5FzFX5T.png =700x) ---- 因為這題的最大值有單調性的限制,所以右上角和左下角絕對不會有最大值,剩下紅色部分的陣列要找 ![image](https://hackmd.io/_uploads/HJWB7t7cT.png =700x) ---- 一直二分下去,複雜度是$O(MlogN)$ ![image](https://hackmd.io/_uploads/rkM4NKQ9p.png =700x) --- ## 例題:[糟糕陣列](https://neoj.sprout.tw/problem/128/) 給你一個$N$,你要生出$N*N$的二維陣列,對於所有$i$ $(1 \leq i \leq N)$,使得「第$i$列的所有數值」和「第$i$行的所有數值」聯集起來為{$1,2,...,2N-1$} $(1 \leq N \leq 1024)$,存在一正整數$K$使得$N=2^k$ ![image](https://hackmd.io/_uploads/HyGckcXcp.png =350x) ---- 一樣先想一下怎麼分治:D,你可以隨便生一個$4*4$的陣列放數字看看,也可能需要通靈一下 ![image](https://hackmd.io/_uploads/BkEjqKyoT.png =350x) ---- 試著把一個數字放在(i,i)的位置 ![image](https://hackmd.io/_uploads/SkJ5cKJoT.png =350x) ---- 再把一個數字亂放在某個位置上,像是把2放在紅色的位置,會有以下兩種可能,那我們要取哪種呢 ![image](https://hackmd.io/_uploads/S1_FitJsT.png) ---- 既然我們分治的觀念是解決小問題合併到大問題 那相同的小問題重複越多越好,我們寫code就不用思考太多 我們盡量把左上四塊、右下四塊長得一樣 ![image](https://hackmd.io/_uploads/ryaD2K1ja.png =350x) ---- 無腦填3,剩下[4,5,6,7] ![image](https://hackmd.io/_uploads/SyfXTtJjp.png =350x) ---- 隨便填4,假設放在下面紅色的位置,會有兩種可能 ![image](https://hackmd.io/_uploads/SytpTKyiT.png) ---- 經過一番亂填之後,上面的這兩種可能 可能會長得像這樣 ![image](https://hackmd.io/_uploads/rJurMcJjp.png) 看起來好像都是對的,那哪個比較好做、有規律呢? ---- 對於左邊的圖,你要去紀錄左下角$2*2$方格的4,5,6,7放在哪裡 再去放右上角$2*2$方格的4,5,6,7 左下角和右上角的排列方式會不太一樣 ![image](https://hackmd.io/_uploads/HkDZzcJsT.png =350x) ---- 反觀右邊的圖 左下角$2*2$方格只有4,5兩種數字,右上角$2*2$方格只有6,7兩種數字 並且排列方式基本一模一樣 ![image](https://hackmd.io/_uploads/ryn0J5yoT.png =350x) ---- 既然排列方式一模一樣,不難發現這可能就是解決這題的一種方法 ---- 可以試試在這個二維方格切兩刀,分成四個$2*2$方格 在1~7這些數字中 選1,2,3到左上右下、4,5到左下、6,7到右上 按照規律去排數字 ![image](https://hackmd.io/_uploads/BJpAxc1ia.png =350x) ---- 因為每次都是分成大小一樣的四塊,往下遞迴左上左下右上三塊,加上要填完所有的格子,複雜度為$O(3^{logN}+N^2)$ --- ## 例題:[Max to the right Min](https://codeforces.com/problemset/problem/1849/E) 給一個長度為$n$的序列,序列為$1$~$n$的permutation,有幾個子區間符合「區間中最大的數字出現在區間中最小的數字右邊」。 ---- 思考時間:D 先透露這裡分治要二分,如果說兩個小區間的答案已經算完了,目前只要思考如何計算跨越兩個區間的答案就好了 可以仔細想一下有哪些case要考慮? ---- 1. 最大在右邊,最小在左邊 ![image](https://hackmd.io/_uploads/SkzPQSE9T.png =300x) 2. 最大和最小值都在左邊 ![image](https://hackmd.io/_uploads/S1JeA1Fq6.png =300x) 3. 最大和最小值都在右邊 ![image](https://hackmd.io/_uploads/Byo2MB4qa.png =300x) 你想到了嗎:D ---- 不難發現你可能會需要前綴、後綴、最小值、最大值這些東西 所以我們弄出來左區間的後綴最小最大值、右區間的後綴最小最大值 ![image](https://hackmd.io/_uploads/HkoIqUVcp.png) ---- 先來處理第一個case 對於一個合理的區間$[L',R']$,需要符合兩個情況 - 後綴最小值 $_{L'} <$ 前綴最小值 $_{R'}$ - 後綴最大值 $_{L'} <$ 前綴最大值 $_{R'}$ ![image](https://hackmd.io/_uploads/rkKKjLN9a.png =500x) ---- 因為這些前綴後綴最小最大值們都有單調性,你要找符合兩個情況的數字可以用二分搜分別去找。 ![image](https://hackmd.io/_uploads/HJik68E9T.png) ---- 那他們交集的位置就是L'可能的位置 你可以掃過右區間的每個位置當作R',做一遍。 這個case就解決了 ![image](https://hackmd.io/_uploads/By5kCLE9a.png) ---- 關於第二個case,最大和最小值都在左邊,看一下合理的區間[L',R']有什麼性質 ![image](https://hackmd.io/_uploads/rkB2xgK96.png) ---- 沒錯!!!!!就是 - 後綴最小值 $_{L'} <$ 前綴最小值 $_{R'}$ - 後綴最大值 $_{L'} >$ 前綴最大值 $_{R'}$ ![image](https://hackmd.io/_uploads/HJFDVeFqT.png) ---- 所以其實跟第一個case一樣可以利用二分搜找到交集的位置 還要多判斷左區間的Max有沒有在左區間的Min右邊 第三個case也是大同小異。 ![image](https://hackmd.io/_uploads/Skxj4lKca.png) ---- 總體複雜度是$O(nloglogn)$,上述所講的二分搜可以用雙指針優化成$O(nlogn)$,大家可以自己想一下怎麼移指針:D --- ## 例題:[好的連續子序列😈](https://neoj.sprout.tw/problem/788/) 給一個長度為$n$的序列,序列為$1$~$n$的permutation,有幾個子區間里的元素排序之後是公差為$1$的等差數列。 $1 \leq n \leq 5\cdot 10^5$ ---- 一樣,思考時間:D 這裡給點提示,定義$Max$是子區間的最大值、$Min$是子區間的最小值: - 一個區間$[L,R]$要滿足: $R-L+1=$$Max$$-$$Min$$+1=$區間長度 - 橫跨中間的子區間又要分成幾種情況? ---- 誒,好像跟上一題類似,這裡分4個case 1. 最小值和最大值都在左區間 ![image](https://hackmd.io/_uploads/rJK815L9p.png =350x) 2. 最小值和最大值都在右區間 ![image](https://hackmd.io/_uploads/BkCwk98qa.png =350x) ---- 3. 最小值在右區間,最大值在左區間 ![image](https://hackmd.io/_uploads/HJ8Yx9Ic6.png =400x) 4. 最小值在左區間,最大值在右區間 ![image](https://hackmd.io/_uploads/ryObx589a.png =400x) 你想到了嗎:) ---- 先講第一個case,講完之後你就會做第二個case了 一樣需要前綴後綴最大值最小值 用下面的區間來舉例 ![image](https://hackmd.io/_uploads/ry93o5U5p.png) ---- 第一個case為:「最大值和最小值都在左區間」 你可以先決定一個$L'$指針代表一個合法的區間左界觀察看看 假設$L'$在下圖的這個位置 ![image](https://hackmd.io/_uploads/Sy24AcU96.png) ---- 既然這個case叫:「最大值和最小值都在左區間」 那圖中已經赤裸裸地跟你講了最大值和最小值應該要是多少 ![image](https://hackmd.io/_uploads/BJs1eoIqT.png) ---- 提示一:$R-L+1=$$Max$$-$$Min$$+1$ 有了最大值、最小值、以及$L'$在哪個地方。 區間長度和、$R'$的位置就可以得出來了 ![image](https://hackmd.io/_uploads/rJRrmoU9p.png) ---- 要滿足最大值和最小值都在左邊 那右邊一定不能出現更大的值或更小的值 所以要去檢查$R'$的前綴最大值和最小值 ![image](https://hackmd.io/_uploads/B1EcEsLc6.png) ---- 經過檢查之後發現他是一個合理的區間 你可以把$L'$從$L$到$mid$計算一遍 那第二個case也是相同道理 ---- 好的,相對難的case要來了 接著是第三個case:「最小值在右區間,最大值在左區間」 觀察這兩個區間,用一個合理的$[L',R']$,來想想要怎麼做 ![image](https://hackmd.io/_uploads/SykCmnv9a.png) ---- 首先,既然最小值在右區間,最大值在左區間的話 代表 - 後綴最小值 $_{L'} >$ 前綴最小值 $_{R'}$ - 後綴最大值 $_{L'} >$ 前綴最大值 $_{R'}$ ![image](https://hackmd.io/_uploads/r1GtE2wcp.png) ---- 會發現好像跟上一題一樣 可以用雙指針或二分搜找到合理的區間 圖中的例子可以找到兩個合理的$R'$ ![image](https://hackmd.io/_uploads/SkE-UhD5T.png) ---- 這時候有一個問題? 兩個$R'$都可以採用嗎? ![image](https://hackmd.io/_uploads/SkE-UhD5T.png) 你會發現偏左的<!-- .element: class="fragment" data-fragment-index="1" -->$R'$<!-- .element: class="fragment" data-fragment-index="1" -->不能是一個合理的<!-- .element: class="fragment" data-fragment-index="1" -->$R'$<!-- .element: class="fragment" data-fragment-index="1" --> 它不滿足<!-- .element: class="fragment" data-fragment-index="1" -->$R-L+1=$<!-- .element: class="fragment" data-fragment-index="1" -->$Max$<!-- .element: class="fragment" data-fragment-index="1" -->$-$<!-- .element: class="fragment" data-fragment-index="1" -->$Min$<!-- .element: class="fragment" data-fragment-index="1" -->$+1$<!-- .element: class="fragment" data-fragment-index="1" -->這個式子<!-- .element: class="fragment" data-fragment-index="1" --> ---- $R-L+1=$$Max$$-$$Min$$+1$這個式子我們可以化簡成 $R+Min=L+Max$ 因此我們要找哪些$R'$滿足上面這個式子 ---- 由於$L'$已經確定了,代表$L'+Max$為一個定值 右邊有很多種$R'+Min$,你可以用一個陣列$cnt$紀錄每種$R'+Min$的次數,然後找$cnt[L'+Max]$就好了 --- 來練習8 [題目連結](https://vjudge.net/contest/605791)

    Import from clipboard

    Paste your markdown or webpage here...

    Advanced permission required

    Your current role can only read. Ask the system administrator to acquire write and comment permission.

    This team is disabled

    Sorry, this team is disabled. You can't edit this note.

    This note is locked

    Sorry, only owner can edit this note.

    Reach the limit

    Sorry, you've reached the max length this note can be.
    Please reduce the content or divide it to more notes, thank you!

    Import from Gist

    Import from Snippet

    or

    Export to Snippet

    Are you sure?

    Do you really want to delete this note?
    All users will lose their connection.

    Create a note from template

    Create a note from template

    Oops...
    This template has been removed or transferred.
    Upgrade
    All
    • All
    • Team
    No template.

    Create a template

    Upgrade

    Delete template

    Do you really want to delete this template?
    Turn this template into a regular note and keep its content, versions, and comments.

    This page need refresh

    You have an incompatible client version.
    Refresh to update.
    New version available!
    See releases notes here
    Refresh to enjoy new features.
    Your user state has changed.
    Refresh to load new user state.

    Sign in

    Forgot password

    or

    By clicking below, you agree to our terms of service.

    Sign in via Facebook Sign in via Twitter Sign in via GitHub Sign in via Dropbox Sign in with Wallet
    Wallet ( )
    Connect another wallet

    New to HackMD? Sign up

    Help

    • English
    • 中文
    • Français
    • Deutsch
    • 日本語
    • Español
    • Català
    • Ελληνικά
    • Português
    • italiano
    • Türkçe
    • Русский
    • Nederlands
    • hrvatski jezik
    • język polski
    • Українська
    • हिन्दी
    • svenska
    • Esperanto
    • dansk

    Documents

    Help & Tutorial

    How to use Book mode

    Slide Example

    API Docs

    Edit in VSCode

    Install browser extension

    Contacts

    Feedback

    Discord

    Send us email

    Resources

    Releases

    Pricing

    Blog

    Policy

    Terms

    Privacy

    Cheatsheet

    Syntax Example Reference
    # Header Header 基本排版
    - Unordered List
    • Unordered List
    1. Ordered List
    1. Ordered List
    - [ ] Todo List
    • Todo List
    > Blockquote
    Blockquote
    **Bold font** Bold font
    *Italics font* Italics font
    ~~Strikethrough~~ Strikethrough
    19^th^ 19th
    H~2~O H2O
    ++Inserted text++ Inserted text
    ==Marked text== Marked text
    [link text](https:// "title") Link
    ![image alt](https:// "title") Image
    `Code` Code 在筆記中貼入程式碼
    ```javascript
    var i = 0;
    ```
    var i = 0;
    :smile: :smile: Emoji list
    {%youtube youtube_id %} Externals
    $L^aT_eX$ LaTeX
    :::info
    This is a alert area.
    :::

    This is a alert area.

    Versions and GitHub Sync
    Get Full History Access

    • Edit version name
    • Delete

    revision author avatar     named on  

    More Less

    Note content is identical to the latest version.
    Compare
      Choose a version
      No search result
      Version not found
    Sign in to link this note to GitHub
    Learn more
    This note is not linked with GitHub
     

    Feedback

    Submission failed, please try again

    Thanks for your support.

    On a scale of 0-10, how likely is it that you would recommend HackMD to your friends, family or business associates?

    Please give us some advice and help us improve HackMD.

     

    Thanks for your feedback

    Remove version name

    Do you want to remove this version name and description?

    Transfer ownership

    Transfer to
      Warning: is a public team. If you transfer note to this team, everyone on the web can find and read this note.

        Link with GitHub

        Please authorize HackMD on GitHub
        • Please sign in to GitHub and install the HackMD app on your GitHub repo.
        • HackMD links with GitHub through a GitHub App. You can choose which repo to install our App.
        Learn more  Sign in to GitHub

        Push the note to GitHub Push to GitHub Pull a file from GitHub

          Authorize again
         

        Choose which file to push to

        Select repo
        Refresh Authorize more repos
        Select branch
        Select file
        Select branch
        Choose version(s) to push
        • Save a new version and push
        • Choose from existing versions
        Include title and tags
        Available push count

        Pull from GitHub

         
        File from GitHub
        File from HackMD

        GitHub Link Settings

        File linked

        Linked by
        File path
        Last synced branch
        Available push count

        Danger Zone

        Unlink
        You will no longer receive notification when GitHub file changes after unlink.

        Syncing

        Push failed

        Push successfully