JOISC2020 題解

LOJ3271「JOISC 2020 Day1」建築裝飾 4

有一個顯然的 \(O(n^2)\) 做法,然後用歸納法可以證明任意時刻合法的位置都是一個線段,就可以 \(O(n)\) 了。

要不是這題我纔不會想到優化呢

LOJ3272「JOISC 2020 Day1」漢堡肉

考慮 \(\min R,\max L,\min U,\max D\) 這四個值。

如果 \(\min R\ge \max L\)\(\min U \ge \max D\) 那麼顯然可以退化到一維的情況。

否則,在 \(K \le 3\) 的時候,容易發現邊界的四個交點上至少有一個竹籤,否則無法把所有邊界覆蓋,所以可以枚舉插了哪個交點,刪掉覆蓋這個交點的矩形,然後遞歸。複雜度 \(O(4^Kn)\)

如果這樣搜索不出解,那麼就只能是四個竹籤分別在四條邊界上,相當於是有四個變量。

對於一個矩形,如果和三個邊界有交,即完整地包含了一條邊界,那麼顯然不需要考慮。

如果只和一個邊界有交,那麼就是限制了某一個變量取值在某一個區間內。

如果和兩個邊界有交,那麼就是限制 \(x_1\in [l1,r1]\ or\ x_2\in [l2,r2]\)

不妨設一個 01 變量表示是否有 \(x_1\in[l,r]\) ,那麼這些限制就可以寫成 2-sat 的模型。

由於滿足的限制需要有解,所以如果 \([l1,r1]\cap [l2,r2]=\varnothing\) ,那麼它們不能同時成立。容易發現,只要滿足這些條件,線段的交就一定有解。

於是前綴和優化建邊即可。

LOJ3273「JOISC 2020 Day1」掃除

先考慮沒有插入的時候怎麼做。

對於被推過的灰塵,它們都會在一個形爲折線的邊界上。

對於折線上的灰塵,滿足每次被操作的灰塵一定是一個區間,所以用平衡樹上二分即可找到座標被區間賦值的一段。

而對於之前不在折線上的灰塵,可以提前算出它們在哪一次操作之後會被併入折線。

所以沒有插入的情況可以 \(O(q\log q)\) 解決。考慮如何處理插入。

對於一個詢問,相當於是問一個點經過一段區間的操作之後會到哪裏。

用線段樹拆成 \(O(q\log q)\) 個這樣的詢問,放在若干個區間上。

那麼此時對於線段樹上的一個區間,點集是固定的,就可以按照沒有插入的做法做了。

總點集是 \(O(q\log q)\) 的,而總操作次數也是 \(O(q\log q)\) 的,所以複雜度 \(O(q\log^2 q)\)

還有另外一種做法,感覺更好想一些?

這個等腰直角三角形看着比較不爽,所以用類似線段樹的拆分方法拆成 \(O(n\log n)\) 個矩形。雖然 \(n\) 很大但是子樹內沒有灰塵的矩形顯然沒有必要建出來。

那麼可以發現,對於一次修改,只會影響到 \(O(\log n)\) 個矩形。

而修改對矩形內部造成的影響就是比較簡單的了:座標取 \(\max\) ,或是把某一個範圍內的點全部踢到子樹內。可以用各種神奇數據結構維護。

因爲深度是 \(O(\log n)\) 的,所以要踢出去的時候可以暴力一個一個處理。

LOJ3274「JOISC 2020 Day2」變色龍之戀

update:寫完才發現 \(C_{L_x}\ne C_x\) ,我人傻了……

請自覺忽略關於初始 \(deg=2\) 的所有討論。

考慮暴力枚舉兩個點,看它們在一起有幾種顏色。如果只有一種顏色那麼連一條邊。

那麼最後一個點連出去的邊會有三種:它喜歡的、喜歡它的、顏色相同的。(記爲 1,2,3 類邊)

顯然 cp 關係會形成環,設一個點連向它喜歡的點的邊是它的出邊。

先假設所有點的度數都是 3 。

那麼就可以對於每一個點,枚舉兩個相鄰的點和自己一起詢問,只有一種顏色當且僅當另外兩個點分別是喜歡它的和顏色相同的。由此可以確定它的出邊。

於是可以把所有環邊確定,就能確定顏色相同的點對。

然後考慮各種特殊情況。

  • 1,2 不同,3 與 1,2 中的某一個相同,度數爲 2 。
  • 1,2 相同,3 與 1,2 不同,度數爲 1 。
  • 1,2,3 均相同,度數爲 1 。

可以發現對於度數爲 1 的點,它的 cp 也是度數爲 1 ,並且它的同色點已經確定了。那麼可以把這些點和它們連出去的邊刪掉。

此時一共只有三類點:

  • 1,2,3 都不同且都存在,度數爲 3 。
  • 1,2 不同,3 被刪掉了,度數爲 2 。
  • 1,2 不同,3 與 1,2 中的某一個相同,度數爲 2 。

並且我們可以知道每一個點是哪一種。

對於一二類點,它的(環上的)出邊在一開始就已經確定了,且出邊顯然不是重邊。

那麼從一個出邊確定的點開始沿着出邊走,就可以得到一整個環的信息。

那麼此時只有一種點的信息沒有確定了:一整個環都是三類點,環邊和重邊交替。

此時選連續的三個點 \(x,y,z\) ,若詢問結果爲 1 則 \(y,z\) 同色,否則 \(x,y\) 同色。

那麼就可以把所有關係都得出來了,就做完了。

然而這個圖還沒能建出來……

注意到這個圖是二分圖,所以必定可以把所有點分成兩個獨立集,獨立集中的點要麼互不影響,要麼是 \(L_{L_x}=x\) 的 cp ,但是後一種情況其實也是互不影響的。

那麼依次加點,求這個點的所有邊,顯然可以在兩個獨立集內分別二分找邊。

於是詢問次數 \(O(n\log n)\)

LOJ3275「JOISC 2020 Day2」有趣的 Joitter 交友

前面的分析不是很難,但是感覺不是很會實現 /px

對於一個集合,維護 \(point\) 表示集合內的點的編號,\(ine\) 表示連入的點的編號, \(inp\) 表示連入的集合編號, \(outp\) 表示連出的集合編號。

合併的時候,先減掉分別的貢獻,合併完成後再加上一整個的貢獻。貢獻爲 \(f(S)=|S|\times (|S|-1)+|S|\times |ine|\)

合併的時候按照 \(|S|\) 啓發式合併,容易發現這樣複雜度一定不會有問題。假設合併 \(x,y\) 之後的集合編號定爲 \(y\)

先把 \(point\)\(ine\) 無腦合併起來。

對於 \(v\in outp_x\) ,有 \(x\in inp_v\) ,需要改成 \(y\in inp_v\)\(v\in inp_x\) 同理。

對於 \(z\in (inp_x\cap outp_y+outp_x\cap inp_y)\) ,需要進一步合併 \(y,z\) ,把這些點對存在一個隊列裏依次合併。

既然都啓發式合併了,所以入隊列的總點對自然應該也不會太多。

LOJ3276「JOISC 2020 Day2」遺蹟

胡出正解了好激動

爲了方便+能做,假設同一個數的兩個分身是不同的,最後再乘 \(2^{-n}\)

先考慮怎樣可以在不暴力模擬的情況下得到一個序列是否合法。

按照值域從大到小考慮,以 223311 爲例。

先看到兩個 3 ,那麼右邊那個保留下來,左邊那個會變成 2 ;

然後有三個 2 ,仍然保留最右邊的 2 ,其它 2 或早或晚都會變成 1 。

最後有四個 1 ,保留最右邊的 1 。

然而這樣還是不太好計數。

轉換成從右往左考慮,維護 \(vis_x\) 表示數 \(x\) 是否有被定下來位置。加入一個數 \(y\) 的時候 while (vis[y]) --y; ,即可知道它會變成什麼,或是被刪掉。

但是顯然 DP 的時候也還是不能把 \(vis\) 存下來。

注意到我們最主要關心的是 \(vis\) 的極長前綴 1 的長度,所以不妨只記這個東西。

那麼當前位置要被刪掉的時候就可以轉移了,而如果當前位置要被加入的話,就枚舉加入之後極長前綴 1 的長度會變成什麼,計算貢獻。

https://www.cnblogs.com/dysyn1314/p/12877113.html 神仙dy的博客講得更加詳細。

LOJ3277「JOISC 2020 Day3」星座 3

我也忘記怎麼做了……建出笛卡爾樹之後線段樹合併亂搞一通好像就行了。

https://loj.ac/submission/772893

LOJ3278「JOISC 2020 Day3」收穫

想到思路不難,不過實現也有一些細節。

顯然果樹之間兩兩獨立,而一棵果樹被某個人摘了之後下一次被摘顯然是這個人往後第一個距離超過 \(C\) 的人。這樣連一條邊即可連出一個基環內向樹。

對於樹上的情況,相當於詢問子樹內某個權值小於等於某個數的果樹個數,隨便做。

對於環,可以先把環上的一條邊斷掉,算出不經過這條邊的貢獻,然後把所有果樹都移到這條邊指向的點。

此時的詢問就可以被看做一個二維數點(走過來的時間不能太長,然後按照模環長的餘數分類),離線一下即可 \(O(n\log n)\)

https://www.cnblogs.com/dysyn1314/p/12582983.html 神仙dy的博客講得更加詳細。

UOJ509. 【JOISC2020】迷路的貓

關於LOJ,它咕了

竟然又直接搞出正解了,爽啦

對於 \(A\ge 3\) 的情況,有這麼一種構造方法:

把 BFS 樹建出來,那麼我們想要每個點每一步都能使得 \(dep=dep-1\)

既然有三種顏色,那麼可以搞出這麼一種大小關係: \(0<1,1<2,2<0\) ,然後對於每個點,把能走的標成一種顏色,不能走的標成比它大的一種顏色。

其實就是把顏色標爲 \(dep_x\%3\)

然後只考慮 \(A=2,m=n-1,B\ge 6\)

如果每一個點的兒子數量都不是 1 ,那麼容易發現只需要按深度黑白染色即可。

所以考慮鏈應該怎麼做。

把鏈上的邊循環染色,一個循環節爲 BBWBWW

盯着這個串 BBWBWWBBWBWWBBWBWWBBWBWW...

如果起始點旁邊是 WWBB ,那麼沿着某一個方向連走兩步,就可以確定哪一邊是根的方向了。

否則,先往 B 走一步。如果此時走到了 BB 那麼同樣按照上面的方法就可以知道哪一邊是根了。

否則再往同樣的方向走一步,那麼可能走到 WWBW ,也就知道哪邊是根了。

知道哪邊是根之後就很好搞定了,不走回頭路即可。此時多走的步數恰好最多爲 6 。

怎樣套回到一棵樹上呢?

設根(即終點)是 \(x\) ,那麼顯然根的每一棵子樹的染色方案互不影響,設某一個兒子是 \(y\)

如果之前沒有定下來 \((x,y)\) 的顏色,那麼不妨欽定它是 B 。以下都假設 \((x,y)\)B ,如果是 W 就把循環節循環移位一下變成 WWBBWB ,顯然前面的討論是不變的。

考慮 \(y\) 有幾個兒子:如果有超過 1 個,那麼把這些邊全都變成 W ,然後發現只要能走到 \(y\) 就可以走到 \(x\) ,所以可以遞歸 \(x=y,y=son\)

否則,設 \(y\) 往下第一個不止一個兒子的點是 \(z\) ,那麼把 \(x\to z\) 這一段按照鏈的方法染色,\((z,son_z)\) 的顏色設爲 \((fa_z,z)\oplus 1\) ,然後遞歸。

分析一下正確性:如果出生點是 \(z\) 或是 \(z\) 的子樹,那麼直接可以往鏈上走,然後不走回頭路一路走到 \(x\) ,且沒有多餘步數;否則如果出生在鏈上,就可以按照鏈的做法做,同樣能找到 \(x\)

顯然如果鏈不夠長,在走鏈的過程中一不小心走到了 \(x\)\(z\) ,那麼也可以直接確定根的方向。

於是做完了。

LOJ3280「JOISC 2020 Day4」首都城市

不能想太多,暴力一點就贏了……

考慮建圖: \(x\to y\) 當且僅當 \(x\) 城市的小鎮組成的虛樹中包含 \(y\) 城市的小鎮。那麼縮點之後就是出度爲 0 的強連通分量大小的 \(\min\)

這個建圖用倍增優化即可。

LOJ3281「JOISC 2020 Day4」傳奇糰子師傅

一開始胡了個二分圖匹配,然後發現白色可能會被用多次,然後就自閉了……

亂搞即可。不想學了。

LOJ3282「JOISC 2020 Day4」治療計劃

想象一下按照時間順序模擬的情況:會有若干個健康區間,每次加入區間的時候可能會合並,然後隨着時間往後推左右端點往裏縮。

然後……感受一下就可以得到這麼一個做法:不再按時間模擬,而是從左往右加區間,最後要把區間連成 \([1,n]\)

兩個區間可以並在一起當且僅當 \(r_i+1\ge l_j+|t_i-t_j|\)

然後類似最短路轉移。令邊權爲指向的點的點權。

爲了優化最短路的過程,把絕對值拆開,把點按 \(t_i\) 排序,然後用兩棵線段樹分別維護區間中 \(l_j\pm t_j\) 的最小值和取到最小值的位置,轉移的時候把一整個前綴中合法的點都轉移掉,並在線段樹中刪除。

一個點只會被轉移一次、刪一次,所以複雜度 \(O(n\log n)\)

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章