2017 CERC


2017 CERC

Problem A:Assignment Algorithm

題目描述:按照規則安排在飛機上的座位。

solution
模擬。

時間復雜度:\(O(nm)\)

Problem B:Buffalo Barricades

題目描述:將二維平面划分為一個個單位格,在平面上有一些被標記的格子。將\(x,y\)軸當成是圍欄,現在以此給出一些坐標,每次從那個坐標出發向\(x, y\)軸建圍欄,並輸出新圍欄圍住的被標記格子數。

solution
待解決。

C:Cumulative Code

題目描述:給出一棵深度為\(K\)的滿二叉樹,逐層從左到右編號,然后寫出滿二叉樹的prufer code(假設為\(P\)序列)。prufer code:每次選擇一個編號最小的葉子節點,然后記錄它的鄰居編號,再把這個葉子節點刪去,重復操作,直至只剩下兩個節點。記錄下來的編號序列就是prufer code。現在有\(q\)個詢問,每次詢問有三個參數\(a, d, m\),表示求\(P_a, P_{a+d}, ... , P_{a+(m-1)d}\)的和。

solution
將子樹分成兩類。
\(A\)

這類子樹是先移除左子樹,再移除右子樹,最后移除根。

\(B\)

這類子樹是先移除左子樹,再移除根,最后移除右子樹。

先分析\(A\)類子樹,\(B\)類子樹做法類似。

\(f_x(k)\),表示根為\(x\)的子樹深度為\(k\)(只有\(x\)時深度為\(1\))的prufer code和。則
\(f_x(1)=x/2\)
\(f_x(2)=2x+x/2\)
\(f_x(3)=10x+2+x/2\)
\(f_x(k)=a_k \cdot x+ b_k + c_k \cdot (x/2)\)

\(f_x(k)=f_{2x}(k-1)+f_{2x+1}(k-1)+x/2\)
\(=a_{k-1} \cdot 2x +b_{k-1}+c_{k-1} \cdot x + a_{k-1}(2x+1) +b_{k-1}+c_{k-1} \cdot x +x/2\)
\(=(4a_{k-1}+2c_{k-1})x+(a_{k-1}+2b_{k-1}) + x/2\)
\(\therefore a_k=4a_{k-1}+2c_{k-1}, b_k=a_{k-1}+2b_{k-1}, c_k=1\)
\(Q={a, a+d, ..., a+(m-1)d}\), \(next_{Q}(i)\)表示\(Q\)序列內大於等於\(i\)的最小編號。
\(g_x(k, i)\)表示以\(x\)為根,深度為\(k\)的子樹,在對該子樹進行操作前已有\(i\)prufer code(原樹的),在\(Q\)中的\(P\)和。按照類似\(f_x(k)\)的記錄方式,同樣也可以如此記錄\(g_x(k, i)\)。則
\(g_x(k, i)=g_{2x}(k-1, i)+g_{2x+1}(k-1, i+2^{k-1}-1)+((i+2^k-1) \in Q) \cdot (x/2)\)
加快\(g\)的遞歸計算。

  1. 如果\([i+1, i+2^k-1]\)中沒有在\(Q\)中的編號,則直接返回
  2. 記憶化一些狀態:當\(k \leq K/2\)\([i+1, i+2^k-1] \in [a, a+(m-1)d]\)時進行記憶化,記憶化的關鍵字為\((k, next_Q(i)-i)\)

由於有條件\(1\),所以\(next_Q(i) \leq i+2^k-1\),所以最多有\(2^{K/2}\)種狀態需要記憶化。
剩下還有幾種情況:

  1. \(B\)類樹,但\(B\)類樹最多計算\(K\)
  2. \(k>K/2\)時,這里會調用\(2^K\)次。
  3. \([i+1, i+2^k-1]\)\([a, a+(m-1)d]\)相交,但\([i+1, i+2^k-1]\)不在\([a, a+(m-1)d]\)內,這種情況最多有\(K\)次。
    所以每個詢問的時間復雜度為\(O(2^{K/2})\)

時間復雜度:\(O(2^{K/2}q)\)

Problem D:Donut Drone

題目描述:有一個\(r \times c\)的網格,每個格子有一個整數。現在從第一列的指定一格出發,每次移動一步是這樣的:選擇右邊相鄰一列的相鄰三個格子(右上,右,右下)中整數最大的格子。第一列與第\(c\)列是相鄰的,第一行與第\(r\)行也是相鄰的。現在有兩種操作:1、移動\(k\)步,輸出移動后的坐標。2、修改某個格子的數字。

solution
預處理出\(jump[row]\)表示從第一列的第\(row\)行出發,移動\(c\)步回到第一列的第\(jump[row]\)行。這樣就可以\(O(1)\)移動\(c\)步,根據鴿巢原理,\(jump[row]\)是一個環,所以\(O(r)\)能完成任意步的移動。
問題在於操作2。通過觀察,可以得知第一列能走到\((x, y)\)的行是一個連續區間,而且修改某個格子的值只會影響左邊三個格子的走向,即另外形成三條路徑,這幾條路徑可以暴力跑一遍,然后暴力修改那個連續區間的\(jump[row]\)值。

時間復雜度:\(O(r+c)\)每次詢問。

Problem E:Embedding Enumeration

題目描述:給出一棵樹,有\(n\)個節點,\(1\)為樹根。現在要將這棵樹放在一個\(2 \times n\)的網格中,每個格子放一個節點,樹上相鄰的點要放在相鄰的格子,\(1\)號點要放在左上角的格子,問有多少種放置方法。

solution
首先可以確定這棵樹是一個二叉樹,否則無解。
\(f(x, delta)\)表示只剩下\(x\)的子樹(不含\(x\))還沒放置,\(x\)放置的那一行放得比另一行長,長\(delta\)格的方案數。
現分情況討論:

  1. \(x\)沒有兒子,則找到一種可行方案。
  2. \(x\)有一個兒子\(y\)
    1. \(y\)可以放在\(x\)的右邊,轉移狀態至\(f(y, delta+1)\);
    2. 也可以放在下面。
      1. \(y\)的一個兒子\(z\)要放在\(y\)的左邊,則\(z\)只能是一條長度不超過\(delta-1\)的鏈。
      2. \(y\)的一個兒子\(v\)放在\(y\)的右邊,則轉移狀態至\(f(v, 1)\)
  3. \(x\)有兩個兒子\(y, u\)\(y\)有一個兒子\(v\)放在\(y\)的右邊。這樣\(u, v\)的子樹都還沒有放置,也只能沿着自己所在那行一直延伸,直至某一行不能延伸,設另一行延伸到\(w\),則轉移狀態至\(f(w, 1)\)

接下來就是想辦法把\(delta\)省掉,具體方法是注意如果將\(f(x, 2)\)視為\(f(x, 1)\),會算漏什么。具體還沒實現。。。

時間復雜度:\(O(n)\)

Problem F:Faulty Factorial

題目描述:將\(n\)的階乘中的一個數\(x\)換成比它小的數\(y>0\),使得換了之后的乘積模\(p\)(質數)等於\(r\)

solution
分情況討論:

  1. \(n \geq 2p\)。如果\(r \neq 0\),則無解,否則將\(p\)變成\(1\)即可。
  2. \(2p > n \geq p\)。如果\(r==0\),則將一個非\(p\)的數變成\(1\)即可,注意:當\(n==p==2\)時無解。若\(r \neq 0\),則將\(p\)變成另一個數,枚舉一下就好。
  3. \(p>n\)\(\frac{M}{x} y \equiv r mod(p), M=n! mod (p)\), 則\(y \equiv rx \cdot inv(M) mod (p)\)。枚舉\(x\),求對應的\(y\),求出一個可行解即可,否則無解。

時間復雜度:\(O(p)\)

Problem G:Gambling Guide

題目描述:給出一個\(n\)個點\(m\)條邊的無向圖,現在從\(1\)號點出發到\(n\)號點,假設現在在\(i\)號點,然后買票,但買到的票是隨機的,即這張票通向的是\(i\)號點相鄰點的隨機一個,買到的票可以不立刻用,也可以不用。問需要期望買多少張票能從\(1\)號點到\(n\)號點。

solution
\(f(x)\)為從\(x\)號點到\(n\)號點的期望買票數。按照最優策略,當買到去\(y\)的票時(\(y\)\(x\)的鄰居),若\(f(y)<f(x)\),則移動到\(y\),否則不動。
現在只知道\(f(n)=0\)。假設\(f(x)\)已知的集合為\(S\),初始時\(S=\) { \(n\) },然后按\(f(x)\)遞增的順序添加點進\(S\)。考慮那些不在\(S\)中,但有鄰居在\(S\)的點\(x\),則

\[f'(x)=1+\sum_{neighbour_y \in S} \frac{f(y)}{degree(x)} + \sum_{neighbour_y \notin S} \frac{f'(x)}{degree(x)} \]

\[f'(x)=\frac{degree(x)+\sum_{neighbour_y \in S} f(y)}{degree(x)-\sum_{neighbour_y \notin S} 1} \]

選擇\(f'(x)\)最小的點添加到\(S\)\(f(x)=f'(x)\)
這個過程與Dijkstra很像,所以可以按照Dijkstra的實現方法來實現。

時間復雜度:\(O(mlogn)\)

Problem H:Hidden Hierarchy

題目描述:給出一些文件的大小,按規則展開目錄,輸出目錄樹

solution
模擬

時間復雜度:\(O(nlogn)\)

Problem I:Intrinsic Interval

題目描述:給定一個\(n\)排列\(P\)。若排列中\([x, y]\)的數從小到大排序后是連續的,則稱它是一個好區間。現有\(m\)個詢問\((a, b)\),問包含\((a, b)\)的最小好區間是哪一個。

solution
離線處理,分治。假設現在處理的詢問都包含在\([L, R]\)中,設\(mid=\frac{L+R}{2}\)。然后將包含在\([L, mid], [mid+1, R]\)的區間分治處理。剩下的就是包含\([mid, mid+1]\)的詢問,然后找出包含\([mid, mid+1]\)的所有好區間,用這些好區間更新詢問的答案。

時間復雜度:\(O(n(logn)^2)\)

Problem J:Justified Jungle

題目描述:給定一個有\(n\)個節點的數,找出所有的整數\(k\),滿足在樹上刪掉\(k\)條邊后,形成的每棵樹的節點數相同。

solution
首先,\(k+1\)一定是\(n\)的因數。隨意找一個點做根,求出每棵子樹的大小。如果某一個\(k\)是答案,則子樹大小是\(\frac{n}{k+1}\)的倍數的個數應該是\(k+1\)。可以證明這是充要條件。

時間復雜度:\(O(nlogn)\)

Problem K:Kitchen Knobs

題目描述:有\(n\)個轉盤,每個轉盤在邊緣上均等寫着\(7\)個數字(\(1\)~\(9\)),現在每次可以選定一個區間\([L, R]\),將區間內的轉盤順時針同時轉動若干次,使得最終每個轉盤表示的數字最大(轉盤表示的數字為:轉盤指向的數字為七位數的最高位,然后順時針依次連接),問應該選擇多少個區間(輸出次數即可)

solution
以下的討論都是基於模\(7\)的情況。
首先觀察可得,每個轉盤轉動次數要么是確定的,要么怎么轉都可以。所以可以假設只有\(n\)個轉動次數確定的轉盤,每個轉盤的轉動次數為\(a_i\)。問題轉化為每次選擇一個區間加上一個相同的數,使得最終\(a_i=0\)
\(b_i=a_i-a_{i-1}\),將區間操作轉化為點操作。將\(b_i\)分成盡量多的組,使得每一組的和等於\(0\),原題的答案等於\(n\)-組數。因為將某一組\(b_i\)全變為\(0\)的次數為該組中的個數減一。
問題就轉化為將\(b_i\)分成盡量多的組,使得每一組的和等於\(0\)
首先將每個\(0\)歸為一組,然后\(1, 6;2, 5;3, 4\)匹配,最終只剩下最多三種不同的數字,然后用\(dp\)算出答案。\(f[i][j][k]\)表示每種數剩下多少個分得的最多組數。

時間復雜度:\(O(n^3)\)

Problem L:Lunar Landscape

題目描述:在二維平面上有\(n\)個正方形,這\(n\)個正方形的中心的坐標和頂點的坐標都是整數,而且這些正方形的邊要么與\(xy\)軸平行,要么成\(45^{\circ}\)。問正方形覆蓋的面積。

solution
將平面上的每個格子用對角線分成\(4\)格,將兩種正方形分別進行二維部分和,然后將部分和合並。

時間復雜度:\(O(平面大小)\)


免責聲明!

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



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