HN2018省隊集訓


HN2018省隊集訓

Day1

今天的題目來自於雅禮的高二學長\(dy0607\)

壓縮包下載 密碼: 27n7

流水賬

震驚!穿着該校校服竟然在四大名校暢通無阻?霸主地位已定?

\(7:10\)從校門口出發,坐公交幾站就到了雅禮了,一種比我們學校高到了不知道哪里去的既視感。

在門口咕咕咕了半個小時,進了一個比較破舊的機房。

一股我們學校\(4\)機房既視感。然而4機房暑假也要裝修了

只有\(Win7\),我忽然覺得今天可能會有點小麻煩了。

還是好好看題為妙。

先看\(T1\),一眼感覺像\(LCT\),隨手敲了幾行,先看看后面的題目。

第二題怪怪的,先跳。

第三題一臉多項式既視感,一眼會\(O(nk^2)\)\(dp\)

回去看\(T1\),忽然感覺不需要\(LCT\),可以樹鏈剖分+大力討論解決。

主要的問題在於怎么在換根之后求\(LCA\),只需要大力討論一波就可以了。

雖然有\(gdb\),但是在\(Win7\)下不太會用,調了兩個小時才寫過打樣例,\(Dev\)的調試太不舒服了。

然后看\(T2\),畫下圖,發現就是在一個梯形中找一個最小的元素。

因為同一列的元素可以直接計算,相當於只需要在\(y=1\)上面找就可以,復雜度\(O(nq)\)

發現可以過\(27\)分。

\(T3\),直接寫出來\(O(nk^2)\)\(dp\),這個東西就是\(46\)分。

接着發現每次轉移都是一個卷積,用\(NTT\)做就好了,時間復雜度\(O(nklogk)\),這樣有\(59\)分。

再回頭看\(T2\),發現有隨機數據,再看看上面的式子,發現具有單調性。

所以用一個單調棧維護一下,每次計算的時候只需要跳到下一個比他小的位置計算就好了。

這樣就可以有\(42\)分了?

接着想\(T3\),總覺得可以多項式快速冪什么的預處理一下,然后就可以變成\(O(klognlogk)\)

但是思考了很久,發現總是有一個\(2^k\)搞不掉,也沒有辦法了。

所以,今天的期望得分:\(100+42+59=201\)

然而,實際得分\(62+42+59=163\)

\(T1\)發生了什么呢?我明明都開了$long\ long $了啊。

打開程序,發現我在放置標記的時候沒有開\(long\ long\),而我下放標記就是用放置標記寫的。

導致有兩個\(SubTask\)錯了點,從而少了分。

簡答的題解

T1.Tree

題意

給你一棵樹,有三個操作

換根,把兩點的\(lca\)的子樹點權全部加上\(w\),詢問某個點的子樹權值和。

題解

先拿\(1\)當做根進行樹鏈剖分。以下的子樹,\(lca\)都是相對於以\(1\)為根而言。

考慮換根后怎么求兩點的\(lca\),如果一個點在根的子樹內另外一個點在子樹外,那么\(lca\)就是根。

否則,先求出兩點在以\(1\)為根的樹中的\(lca\),記兩點\(u,v\)\(lca\)\(x\)

如果根在不在\(x\)的子樹中,顯然需要的\(lca\)就是\(x\)

否則,就是沿着根向上跳,與\(u-lca-v\)路徑的交點。

這個對\((x,u)\)\((x,v)\)\(LCA\)就可以判斷。

至於一個點在當前根下的子樹,還是分根在當前點子樹內還是當前點子樹外考慮。

如果在當前點\(u\)子樹內的話,設根到\(u\)的路徑上,最靠近\(u\)的點是\(v\)

這樣子在當前根下\(u\)的子樹就是整棵樹除去\(v\)的子樹。

否則在當前點的子樹外,則子樹就是以\(1\)為根時的子樹。

這樣子分類討論一下就好了。

代碼戳這里

T2.Function

題意

有一個\(10^9\times n\)的網格,每一列的格子都擁有相同的點權,每次可以向上或左上走一次,直到最上面那行。

求路徑上格子點權和的最小值。

題解

首先,無論那種走法,一定等價於先向左上走一段,再一直向上。

所以我們可以一個\(O(nq)\)的暴力,設當前詢問點\((x,y)\)

我們向左走到\(i\),那么貢獻就是\(s[y]-s[i]+A[i]\times (x-y+i)\)

考慮一下對於任意\((x,y)\),我們把貢獻拆成三個部分來看。

第一部分:\(s[y]\),定值,對結果沒有任何影響。

第二部分:\(A[i]\times i-s[i]\),只與\(i\)有關的式子,與詢問無關,也是定值。

第三部分:\(A[i]\times (x-y)\),與詢問有關。

我們先往回考慮暴力,我們從大往小枚舉\(i\),那么如果當前的\(i\)比之前的那個更優

一定滿足\(a_i\)單調,否則一定不會更優。

所以對於本題純隨機的數據,可以用單調棧提前預處理,這樣子只需要跳第一個比他小的位置就好了。

那么回歸上面的貢獻的三個部分。

我們發現第一和第二部分是不變的,因此只需要考慮第三部分。

第三部分直接考慮顯然就變成了暴力,我們考慮把所有的詢問一起考慮。

我們按照\(y\)排個序,這樣子的話,選擇每個點的作為最優值的情況都是一段連續的\(x\)

既然按照了\(y\)排序,所以我們順次插入所有的\(a_i\),用一個單調棧維護一下每個點掌握的\(x\)的區間。

每次新插入點的時候,考慮當前點會不會比棧頂的點更優,如果更優就直接彈出去。

然后考慮如何計算這個點掌握的\(x\)軸的范圍,這個二分一下就好了。

然后如何計算答案,顯然在棧內二分一下,看看這個詢問的\(x\)應該從哪個點轉移過來就好了。

代碼戳這里

T3.Or

題意

\(n\)個數\(a_i\),每個數的范圍都是\([1,2^k]\),設\(a_i\)\(or\)前綴和\(b_i\)

\(b_i=a_1\ or\ a_2\ or\ ...\ or\ a_i\),要求\(b\)單調遞增,求滿足條件的數列\(a\)的個數。

題解

考慮一下\(dp\),設\(f[i][j]\)表示前\(i\)個數用了\(j\)個二進制位的方案數

\[f[i][j]=\sum_{k=1}^{j}f[i-1][j-k]\times C_{j}^k\times 2^{j-k} \]

\[\frac{f[i][j]}{j!}=\sum_{k=1}^{j}\frac{f[i-1][j-k]\times 2^{j-k}}{(j-k)!}\times \frac{1}{k!} \]

最后的時候再額外乘一下\(C_K^j\)就好了。

我們發現這是一個卷積形式,令\(F_i(x)\)\(f[i][j]/j!\)的指數型生成函數

那么,$$F_i(x)=F_{i-1}(2x)\times(e^x-1)$$

每一步都只需要考慮后面那一部分,剩下的遞歸計算一下。

我們發現$$F_n(x)=\prod_{i=0}^{n-1}(e^{2^ix}-1)$$

考慮如何快速計算后面的累乘式,我們利用倍增來計算。

如果\(n\)是偶數,我們分成前后兩半,設前一半為\(G(x)\),那么后一半為\(G(2^{n/2-1}x)\)

如果是奇數,則把多出來的那一項直接乘到答案里面去,然后剩下的繼續處理。

然后前后兩半乘起來就好了。時間復雜度\(O(klognlogk)\)

代碼戳這里

總結

今天的題目難度並沒有想象中的大,並且部分分也是相當的好拿,今天的暴力寫滿應該就是\(100+42+59=201\)吧。可是我卻沒有拿滿。

還是寫題目的時候的一些小錯誤導致了丟分,以后無論寫什么,寫完之后思考一下數據范圍,如果存在取模或者要用\(long\ long\),一定要好好的檢查一下是否都用了\(long\ long\),或者是否都取好了模。

要像\(HNOI\)的時候的那種狀態,什么題目都好好想清楚,一定不能落下任何細節,做到不犯任何錯誤,做題目也要小心翼翼,不要一下子直接打了一堆東西出來,結果調都給調死,浪費一堆的時間。

Day2

今天的題目來自於\(laofu\)laofudasuanbaofushehui

今天的題面有彩蛋。(霧

今天的包,密碼: hd87

流水賬

在校門口買了點東西吃,碰到了\(xzy\),然后發現了\(zsy\),然后一起去公交車站。

等了一下\(dsl\)\(tjj\),所有人就出發去雅禮了。

今天沒咕咕咕,去的時候已經有人到了,空調也還不錯。

\(8:00\)准時開始考試,看到\(laofu\)的題目瑟瑟發抖,然后果然有一道叫做\(string\)的題目。

先看\(T1\),我會\(O(n^2)\),隨手敲完\(T1\)

再看\(T2\),我們\(O(Tn!)\),等下,\(n\le 5\)直接打表就好,而且樣例連表的告訴你了。

再看\(T3\),什么鬼玩意?我會\(O(n^2)\)。啥?\(O(n^2)\)只有\(n=100\)的十分?

下一檔分就是\(n\le 10^5\)了?

我似乎會分塊的做法,應該可以拿\(40\)分,然而並不會回文樹前端插入的姿勢,沒辦法啊。

把暴力全部碼完,出去上了個廁所。恩?下雨了。

回去忽然發現\(T2\)如果走不通一定是一條斜線穿過去,並且一定隔斷了一個點。

這樣子可以暴力枚舉割了哪里,然后再容斥一下,這樣子\(O(Tn^2)\)

再前綴和優化一下\(O(Tn)\),再用一次前綴和優化一下,\(O(T)\)

好的,\(80\)分到手。

忽然注意到代碼長度不超過\(100kb\),這不是讓我們打表嗎?

大力打了一個表,發現極限要跑\(5s\)

於是把\(80\)分拼起來,然而拼的時候\(gg\)了。。。。

剩下的時間發現\(T1,T3\)都寫不動了。。。。

簡單的題解

T1.Walk

題意

給定一棵樹,每個點有點權。如果一個點的祖先的權值是這個點權值的倍數,

那么可以直接從那個祖先移動過來,問每個點從\(1\)號點過來的方案數。

題解

留坑。

T2.game

題意

有一個\(n\times n\)的方格,在上面放上\(n\)個車,要求車與車時間不能互相攻擊。

問在不經過含有車的格子的情況下,\((1,1)\)\((n,n)\)聯通的車的擺放情況的方案數。

題解

對於一個不合法的方案,一定能夠找到一個位置\((i,i)\)

使得所有的\((x,i+1-x),x\in[1,i]\)都被車給覆蓋。

此時的方案數就是剩下的\((n-i)!\)

同樣的,跨過方格的主對角線的方案是對稱的。

那么這樣子減去所有不合法的方案,發現就是一個階乘的前綴和。

再容斥減去兩側都割開了的方案數,發現是一個階乘的前綴和的前綴和。

這樣子預處理這些東西就可以拿到\(80\)分。

\(10^9\)的數據顯然不是常規做法,發現可以分段打表,然后就可以\(AC\)了。

神TM雅禮老爺機跑5s,我會自己機房隨便跑0.6s就出來了

代碼戳這里,打表部分被我刪掉了

T3.string

題意

給定一個串\(S\),若干組詢問,每次回答\(S[l..r]\)中本質不同的回文串個數。

題解

我在考場上似乎\(yy\)出一種\(O(n\sqrt n)\)\(40pts\)在線做法,然而不會回文樹前端插入的姿勢,只能作罷。

這個想法大概是把原串分塊,設\(p[l,r]\)為第\(l\)塊到第\(r\)塊的回文樹,這個節點總數是\(O(n\sqrt n)\)的。

每次詢問的時候把被他覆蓋的完整的一段已經預處理過的回文樹扣出來,

直接在上面前端插入,后端插入,然后回答詢問。

因為每次插入最多涉及到新加一個節點、修改一個點的兒子信息。

因為插入操作是\(\sqrt n\)次,所以可以用一個棧之類的東西暴力維護一下修改了哪些地方,

然后撤銷這些操作,讓回文樹回到一開始的狀態就好了。

這樣子的話均攤復雜度\(O(Q\sqrt n)\)然而這樣子並不是均攤的,可以卡掉。

還是回到正解。

既然不是強制在線,那么我們考慮一下如何離線解決。

我們把所有詢問按照\(r\)排序,然后我們依次加入字符,考慮以當前字符為結尾的所有回文串的貢獻。

假設當前的串上一次出現的結束位置是\(pos\),這個串的長度為\(len\)

那么,如果某個詢問的左端點\(l\)\(pos-len+1\)之后,

那么,當前新加入的這個串會對於左端點在上述位置之后的所有詢問的答案增加一。

但是,在回文樹上,一個節點表示的串如果出現,那么它所有的回文后綴也必定會出現。

所以,考慮一下這些回文后綴產生的貢獻。

作為當前串的回文后綴,根據對稱性,一定是當前串的回文前綴。

所以,它的最后一次出現位置一定在當前串的上一次的出現位置之前。

那么,因為只要長度不跨過\(len/2\),意味着這一系列的串的長度之差是相等的。

所以我們發現他們對於答案產生的貢獻是連在一起的。(畫個圖就知道了)

所以,把他們的貢獻連在一起修改就好了。

這樣的時間復雜度是\(O(nlog^2n)\)

這道題目也提供了一個非常好的思路,當計算類似本質不同之類的東西時。

將詢問離線,那么,每次插入一個新的位置,考慮它會對哪些左端點所在的詢問會產生貢獻。

對於這一段加上貢獻,有點類似於線段樹優化\(dp\)的操作。

代碼戳這里

總結

明明昨天說了,今天卻又犯腦殘錯誤,我也不知道該說什么好了。

今天的題目總體來說不是很良心,部分分給的不是很足,畢竟laofudasuanbaofushehui

\(120+\)是比較標准的部分分,然而我又一次沒有拿滿,十分蛋疼。

一次次說不再犯傻逼錯誤,結果一次次又犯,真的是什么鬼玩意啊。

從今天開始,一定,一定,一定不再犯某些傻逼錯誤了。

Day3

今天的題目來自於一中的三名學長

壓縮包戳這里 密碼: ndn9

流水賬

今天早上正在糾結去哪里吃早餐,就碰上\(zsy\)了。

早上到的時間大概是\(7:45\)左右。

先看\(T1\),仔細思考了一波,發現自己會一條線段上的做法。

如果把一條線段的做法直接丟到環上,在稍微判斷一下能夠加進來一條線段,

然后就可以過樣例了,水得不行。就暫時沒管了。

\(T2\),一眼會\(O(n^4)\)的暴力,然后一眼感覺鏈是可以做的。

然后開始寫\(O(n^4)\),忽然發現可以寫到\(O(n^3)\),然后碼碼碼。

然后先寫\(T3\),打了個表,看了好久都沒找出一點規律,最后時間不是太多了,直接寫\(10pts\)滾粗。
回去看\(T1\),自己隨手構了一組數據把自己\(Hack\)了。

索性\(rand\ 50\)次,每次\(O(n)check\),對於\(ans\)\(max\),感覺能過,沒管了。

回去寫\(T2\)的鏈,大力推一波式子,但是發現和我的暴力跑少了\(100\)的答案。

后來發現我似乎對於題目的理解有一些偏差,然后改了改就過了。

下午然而發現\(T1\)全部\(RE\)了,回到學校發現是數據水得不行,很多數據都沒有橫跨線段兩端的邊。

意味着只需要把一條線段的貪心拿出來就可以隨便拿分。

簡單的題解

T1.c

題意

有一個環,有\(n\)段圓弧,每段圓弧順時針從\(l_i\)覆蓋到\(r_i\),線段之間端點可以重合。

求能夠選擇的最大圓弧數。

題解

首先,如果一個圓弧被別的圓弧完全不該,那么他就是沒有任何意義的。

排序之后然后用一個棧之類的東西隨便搞一下,就可以搞好了。

並且搞好之后,線段的\(r\)一定遞增,並且不會互相包含。

現在不考慮圓弧,假設圓弧被斷成了線段。

那么這就是一個很顯然的貪心,從最左側的那根線段開始,能夠選就選。

為什么這樣是對的?假設這根可以選,但是沒有選,而選了下一根。

根據上面的結論,\(r_i<r_{i+1}\),那么,當前這一根線段選擇之后導致后面的線段不能選的情況一定不會比\(i+1\)差。

所以能選則選。

現在考慮環,唯一的問題是什么呢?

可能會有一條跨越了\(n\)的線段影響到了前面的抉擇。

考慮如何暴力?我們顯然是選一根橫跨\(n\)的線段,然后圓弧就被斷開成了線段,貪心即可。

但是橫跨\(n\)的線段很多,不能暴力求。

如果數據純隨機,那么隨便\(rand\)個幾十次,每次\(O(n)\)就好了,基本不會錯。

然后這樣子你就可以\(AC\)了。

代碼戳這里

T2.a

題意

給定一棵樹,依次選定\(K\)條路徑,要求每條邊要么被覆蓋\(K\)次,要么被覆蓋\(1\)次,也可以不覆蓋。

求方案數。

題解

考慮一下暴力,我們每次枚舉兩個點之間的路徑作為所有路徑的交。

那么,貢獻顯然由一些點進入這條路徑的兩個端點的子樹構成。

那么,我們可以做一個背包,設\(f[i][j]\)表示在\(i\)的子樹中選中了\(j\)個點的方案數,

同時滿足所有任意兩個點的\(LCA\)都是\(i\)

那么,每次加入一個兒子的時候,這個點要么選擇在這個兒子的子樹中,

形成一個只被覆蓋了一次的路徑。或者選在這個點上面,形成一條只經過所有路徑交的路徑。

那么,兩個點之間形成的方案數就是在兩個點的子樹中各選\(k\)個點,

然后兩兩任意配對的方案數,也就是\(f[i][k]\times f[j][k]\)

所以我們要求的只有\(f[i][k]\),把它記做\(f_i\)

我們把每一個點的\(f[i][j]\)看成一個多項式\(P_i(x)\)

考慮每個點的這個多項式是怎么來的,

顯然是每個子樹的\(size\)可選可不選(也就是進不進子樹),那么就是$$\prod_{v\in Son_i}(1+size_vx)$$

這個多項式的每一項代表着一個\(dp\)值,這個多項式

那么總方案數\(f_i\)就是\([x^k]P_i(x)\times A\) ,其中\(A=1+x+x^2+...\)

也就是$$f_i=\sum_{i=0}^kP_i[x^i]$$

我們顯然可以分治\(FFT\)求出每個點的\(P\)值,因為\(\sum son_i\)\(n\)同階。

所以復雜度是\(O(nlog^2n)\)

但是,注意一個問題,這種情況是在根確定的情況下,並且枚舉的兩點的\(lca\)並非這兩點本身。

如果\(LCA\)是兩點\(u,v\)中的某一個點,那么不妨設是\(u\)

那么\(u\)\(P_u\)顯然不是我們提前求出來的\(P\),它需要減去\(v\)所在的子樹的貢獻,然后加上它父親作為子樹的貢獻

假設\(v\)所在的子樹的那么根是\(a\)\(a\in Son_u\)

然后把它的父親節點看成一個子樹算進去。

顯然是$$P_u(x)\times \frac{(n-size[u])x+1}{size[a]x+1}$$

這個沒必要卷積,\(O(n)\)做即可,因為\(size\)相同的子樹可以合並,

所以在極端情況下,所有點的\(size\)不同的兒子最多只有\(\sqrt n\)

所以總復雜度不會超過\(O(n\sqrt n)\)

這樣的話分別考慮上述兩種情況,讓每個點作為\(LCA\)就可以線性計算了。

總的時間復雜度\(O(nlog^2n+n\sqrt n)\)

模數\(10^9+9\)十分蛋疼,需要\(MTT\)

這題太毒瘤了,我就當一個口胡選手得了。

T3.i

題意

給定三個函數\(f,g,h\)

定義

\[\begin{aligned} &f(n)=\begin{cases} 1&n=1\\ f(n-f(f(n-1)))+1&n\gt 1 \end{cases} \\ &g(n)=\sum_{i=1}^n f(i)\\ &h(n)=h(g(f(n))-f(f(n)))+g(g(n)) \end{aligned} \]

給定\(n\),求\(h(n)\)

題解

打表(或者\(OEIS\)之類的),發現\(f(n)\)的意義是\(n\)這個數在整個數列中出現的次數,並且\(f(n)\)單調不降。

那么\(g(n)\)\(f(n)\)的前綴和,含義就是\(f(x)=n\)的最大\(x\),也即\(n\)在數列中最后一次出現的位置。

\(g(f(n))\)的含義是什么?\(f(n)\)在數列中最后一次出現的位置

\(f(f(n))\)的含義是\(f(n)\)在數列中出現的次數。

那么\(f(n)\)最后一次出現的位置減去\(f(n)\)在數列中出現的次數,

這個值顯然就是\(f(n)-1\)最后一次在數列中出現的位置,也即\(g(f(n)-1)\)

那么\(g(g(n))\)怎么算呢?

我們差分算一下

\[\begin{aligned} g(g(n))-g(g(n-1))&=\sum_{i=1}^{g(n)}f(i)-\sum_{i=1}^{g(n-1)}f(i)\\ &=\sum_{i=g(n-1)+1}^{g(n)}f(i)\\ &=\sum_{i=g(n-1)+1}^{g(n)}n\\ &=(g(n)-g(n-1))n\\ &=nf(n) \end{aligned} \]

所以,\(g(g(n))=g(g(n-1))+nf(n)\)

所以,$$g(g(n))=\sum_{i=1}^n if(i)$$

我們再看看\(h(n)\)的式子,現在就變成了

\[h(n)=h(g(f(n)-1))+\sum_{i=1}^nif(i) \]

我們看看括號里面的東西,表示的是在數列中,\(f(n)-1\)這個數最后一次出現的位置

如果把所有的\(h\)一步步拆開,那么我們發現它就是一堆\(g(g(x))\)的和。

所以我們考慮所有的這樣的和,發現每一次都是把\(f(n)\)的值減一然后進行計算,

最后當\(f(n)=1\)時停止。那么我們倒着來,

依次把所有的\(f(n)=x\)的數加入進\(g\)值中,然后累加起來,這樣我們就可以得到最后的答案了。

因為\(f(n)\)不會太大,所以\(f\)值只需要算到\(10^6\)左右,這樣子可以把\(f\)相同的數給合並起來。

代碼戳這里

總結

今天的題目非常神仙,\(T1\)亂搞題,\(T2,T3\)都有點神仙了。

今天如果亂搞比較到位,應該可以拿到\(100+50+10=160\)的成績吧

然而最后只有\(40+50+10=100\),顯然比較差了。

所以,還是一些奇奇怪怪的地方稍微注意一下,亂搞的時候也要注意一下一些潛在的問題,

可能導致亂搞\(re\),(比如\(rand\)數的時候發現值域是空集,就不需要\(rand\)了)

這段時間好好調整狀態,讓自己考試漸入佳境吧。

Day4

今天的題目來自於退役了還要毒瘤的\(wfj\_2048\)

壓縮包戳這里,密碼:139x

流水賬

只要是\(wfj\)的題目,我就知道今天要涼。

\(T1\)\(HNOI2018\)看錯題版本。一臉會看着\(O(n^5)\),實際\(O(n^4)\)的東西。

發現可以拿到\(30\)分,非常開心。

發現一個很明顯的貪心,如果當前點選擇修,如果它的祖先的邊中有沒修的,那么一定會修祖先。

但是並不知道有什么用。

感覺可以給每次修邊操作二分一個權值,然后讓他恰好做\(n-1\)次,然而並不知道怎么寫。

接着看\(T2\),爆搜,再見。

\(T3\),我連\(O(n^2)\)的暴力都懶得打。

期望得分\(30+15+0=45\)

實際得分\(30+15+0=45\)

一分都沒有丟,很開心。

簡單的題解

T1.y

題意

\(HNOI2018\ D2T3\),把每個兒子修一條邊更改為可以任意修\(n-1\)條邊

題解

\(tags:\)凸優化,貪心,\(dp\)。我不會做。留坑。

T2.s

題意

給定一個\(n\times n\)的方格,保證\(n\)是奇數,令\(m=(n+1)/2\)

每次可以把\(m\times m\)的子矩陣全部取反,

求矩陣元素的和的最大值。

題解

結論題,留坑。

T3.f

題意

數據結構題,需要維護的操作見題面

題解

\(tags:\)動態\(dp\)\(Link-Cut-Tree\)。留坑。

總結

沒有打掛,很開心,阿魯巴了\(wfj\),很開心。

Day5

今天的題目來自於雅禮的兩個人。

壓縮包戳這里 密碼: ayge

流水賬

開考看\(T1\),感覺像個網絡流。

一開始一直在想怎么強制讓一條邊要么流的容量為\(2\),要么不流。

但是顯然這樣不可行。一個多小時都沒有什么思路。

后來忽然發現可以把偶點做二分圖,中間用奇點連起來,這樣就可以了。

然后就寫完了。

忽然有人告訴我是洛谷原題。今天IOI賽制?

\(T2\)沒感覺,一眼\(5\)分我會\(return\ 0\)

\(T3\),一開始沒有任何感覺。

后來忽然發現確定了左端點之后所有東西都是單調的,

也就是最多只有一個點滿足條件,可以直接二分。

那么就只需要快速求一個子串的字典序排名。

一開始還是沒有感覺,后來忽然就會做了。

求出\(SA\)再分類討論,隨便二分一下就好了,然后就寫完了。
期望得分\(100+5+100=205\)

實際得分\(100+5+70=175\)

發生了什么?

應該是:

int RMQ(int l,int r)
{
	int k=lg[r-l+1];
	return min(hg[k][l],hg[k][r-(1<<k)+1]);
}

我寫成了:

int RMQ(int l,int r)
{
	int k=lg[r-l+1];
	return hg[k][l]+hg[k][r-(1<<k)+1];
}

亮點自尋。這樣都TM能過70分?數據得有多水?

題解

T1.marshland

題意

洛谷4142

給定一個\(n\times n\)的矩陣,所有\(i+j\)為奇數的格子都有一個權值

現在有\(m\)\(L\)型,占\(3\)個格子的東西。可以使得拐角的那個格子的權值變為\(0\)

可以不全部用掉,問最小的權值和。

題解

我們假設有權值的點是黑點,沒有權值的點是白點。

那么每次一定是選擇兩個白點和一個黑點然后覆蓋。

所以我們選擇了一個黑點之后,就不能再選擇與之匹配的兩個白點。

如果我們按照黑點建邊,連向白點,發現有一個問題:

可能會有黑點只流出去了一點流量,而並非滿流。

我們沒有辦法可以限制一條邊要么滿流要么不流。

我們換一下思路。考慮到一定是選擇一個白點,然后匹配一個白點。

這個時候相當於是將這兩個白點之間的黑點的權值變成了\(0\)

所以將白點放在兩邊,形成一個類似於二分圖的東西。

同時每個黑點只能夠被有用一次,所以拆點,中間用它的權值作為邊的費用。

發現這樣子還是有問題,如果把所有的白點都拆成兩個顯然是錯的。

我們發現兩個白點一定不在同一列,一定在相鄰的兩列(行也是一樣的)

所以按照每個白點在哪一列進行黑白染色分成兩邊,

強制從奇數列連向偶數列就行了。這樣子就沒有問題了。

代碼戳這里

T2.party

題意

有一棵樹,只能從兒子走向父親。每個點有一個顏色。

每次詢問\(K\)個點,要使得所有點都在他們到\(LCA\)的路徑上選擇若干個點所具有的顏色。

要求每個人選擇的集合沒有交集,並且所有的集合大小相同。求並集的最大值。

題解

顯然可以用\(bitset\)維護出每個人到\(LCA\)路徑上出現的所有顏色。

那么,現在就是每個人只能帶某幾種顏色了,並且顏色不能存在交。

這就是一個二分圖匹配。如果暴力做顯然是二分后拆點+匈牙利計算答案。

事實上並不需要,考慮\(Hall\)定理:

如果存在完美匹配,那么任意選擇\(K\)個左側節點,他們連向右側節點的並的大小不小於\(K\)

我們算出選擇任意個節點的顏色的並,這個可以狀壓遞推解決。

根據\(Hall\),定理,如果\(x\)是答案的話,那么對於任意狀壓后的狀態,都有:

當前狀態的人數乘上\(x\)要大於當前狀態的顏色的並的集合大小。

所以\(x\)就是所有狀態的集合大小整除這個狀態的\(1\)的個數的最小值。

有個優化,樹鏈剖分求\(lca\)到當前點的集合的並,並不需要樹鏈剖分\(log\)再加上線段樹\(log\)

可以提前預處理出每個點跳到重鏈頂端的集合,然后先跳掉和\(lca\)在同一個重鏈上,再用線段樹查詢

這樣跳重鏈和線段樹的操作就分離開了,復雜度只有一個\(log\)

綜上,本題時間復雜度\(O(nlogn\frac{m}{64})\)

代碼戳這里

T3.platform

題意

給定一個串,對於這個串所有本質不同的子串按照字典序從大到小排序

給定每個位置一個權值。

求出所有的\((l,r)\),滿足\([l,r]\)構成的子串的排名等於\([l,r]\)的權值和。

題解

確定左端點之后,發現權值和一定是單調遞增的,而子串的排名一定是單調遞減的。

所以這兩個函數最多只會存在一個交點,所以可以二分這個位置。

那么現在的問題很明顯就變成了如何快速計算一個子串的排名。

思考如何用\(SA\)一個串中本質不同的子串的個數,顯然是\(\sum\)后綴長度-\(height\)

這個的意思是按照字典序排序之后,每個后綴能夠貢獻的本質不同的子串的個數就是

當前這個后綴的長度減去這個后綴和排名在他前面一位的后綴的\(lcp\)

所以考慮當前子串\([l,r]\)的排名。

如何\(l\)這個后綴的和排名前一位的后綴的\(lcp\)\(r\)之前,

顯然答案就是\(\sum_{i=1}^{rk_i-1}len_{SA[i]}-height[i]\),再加上\(r-l+1-height[rk[l]]\)

這個東西顯然可以求出后綴數組之后用前綴和預處理好。

如果與排名前一位的后綴的\(lcp\)包含了\(r\)位置,證明這個串在前面的后綴中曾經出現過。

現在就需要找到它第一次出現的位置。

等價於找到排名最靠前的,與后綴\(l\)\(lcp\)要大於等於\(r-l+1\)的那個后綴。

因為\(lcp\)單調不升,二分之后用\(RMQ\)

時間復雜度(可能是)\(O(nlog^2n)\)

代碼戳這里

總結

今天雖然考的還行,但是又犯了智障錯誤。真的很不應該啊。

雖然\(SA\)的確很久沒打過了,但是這不是\(RMQ\)\(min\)寫成加的理由,一定要注意這些問題。

不過今天\(T1\)的數組還是注意了空間問題,\(T1\)沒有掛。

考場背\(SA\)竟然沒有寫錯,好感動。

Day6

今天的題目來自喻隊和另外一位麓山的學長。

壓縮包鏈接 密碼: qbx1

考試心理歷程

上來就看\(T1\),表示毫無感覺。

然后看\(T2\),也沒感覺。

然后看\(T3\),依舊沒有感覺。

這是\(wfj\)的既視感?

再回頭看\(T2\),似乎可以容斥。

那么就是任選的貢獻,一條邊的貢獻,兩條邊的貢獻,和三元環的貢獻。

調了很久把\(T2\)寫完了。

\(T1\),我會全是數字和\(next\_permutation\)

\(T3\),我會暴力\(Hash\)

期望得分\(20+100+20=140\)

實際得分\(30+70+0=100\)

蛤?\(T3\)用了\(C++11\),然后我開了一個叫做\(hash\)的數組,成功的\(CE\)

\(T2\)中間有一個地方我直接寫了除法,然而可能會直接取模了,導致有些點\(WA\)了。

我也很無奈啊。

簡單的題解

T1.gift

題意

定義兩個排列的相似度為不停交換兩個元素直到兩個排列相同的最小操作次數。

給定兩個排列,排列中有些數為\(0\),表示未知的數。

求所有相似度\(\in [0,n)\)的方案數。

題解

考慮一下如果所有數我們都知道了,應該怎么計算相似度。

有一個\(O(n^2)\)的做法,從頭到尾掃\(A\)數組,如何對應位置相同,則什么也不做。

否則找到\(A\)數組中,當前位置對應的那個數字,交換一下,答案貢獻增加一。

我們把這個模型提取出來,也就是從我們當前的\(A[i]\)連邊連到對應的\(B[i]\)

這樣就形成了一個環,顯然是環里面的所有點順次交換。

所以一個大小為\(x\)的環產生的交換次數為\(x-1\),所以差異度就是\(n\)減去環的個數。

現在的問題在於有些邊我們是未知的,所以現在連出來的東西要么是個已知的環,要么是條鏈。

環對於我們計算沒有太大的影響,可以暫時不用考慮,對於鏈而言,中間的部分是沒有任何意義的,

需要考慮的只有頭和尾兩個點。這樣子也只有三種鏈\(0-x,x-0,0-0\),左右兩個東西分別表示頭和尾。

其中,\(0-0\)的鏈十分自由,暫時不考慮。

剩下的\(0-x\)的鏈和\(x-0\)的鏈我們考慮把它們接在一起。

發現只能\(0-x-0-x\)或者\(x-0-x-0\)這樣接,

不存在\(0-x-x-0\)這樣接,如果這樣的話,這兩條鏈顯然是同一條鏈,會被合在一起計算。

也不存在\(x-0-0-x\)的鏈,因為中間由\(0-0\)組成,需要額外考慮\(0-0\)鏈的影響。

我們現在要考慮的只有環的情況,那么設\(f[i]\)表示用若干相同的\(x-0\)\(0-x\)的鏈,產生至少\(i\)個環的方案數。

因為不好直接計算,我們設\(f[i]\)表示至少產生\(i\)個環的方案數。

我們可以得到如下的式子:$$f[x]=\sum_{i=x}^nC_n^{i}S_i^xA_{m+n-x}^{n-x}$$

其中\(n\)是當前類型的鏈的數量,\(S\)是第一列斯特林數,\(C\)\(A\)分別表示排列和組合,\(m\)表示\(0-0\)邊的數量。

什么意思呢?

形成\(x\)環最少要\(x\)條鏈,我們先從\(n\)條鏈中選擇\(i\)條鏈來拼成\(x\)個環,他們拼接的方案數顯然是第一類斯特林數。

剩下的當前種類的鏈的個數是\(n-i\)個,因為對於\(x-0\)\(0-x\)我們已經知道了一側,

如果要連起來,我們顯然需要選擇另外一側,所以我們給他們來選擇前驅(后繼)

這個前驅(后繼)可以是一條別的鏈,可以是\(0-0\)鏈,也可以自己連向自己形成環。

這樣子就可以保證至少有\(x\)個環。接下來容斥一下,就可以算出恰好有\(x\)個環的方案數。

對於\(x-0\),我們設算出來的結果為\(f[i]\),對於\(0-x\)鏈,我們算出來的結果是\(g[i]\)

現在唯一剩余的情況,就是用\(0-0\)鏈合並\(0-x\)鏈和\(x-0\)

先把\(f\)\(g\)做卷積,這樣表示用兩種鏈形成若干環的情況的答案,並且剩下的鏈一定都是\(0-0\)鏈。

為什么剩下的都是\(0-0\)鏈?如果在前面選擇前驅(后繼)的時候,要么就會若干個連成一個一個環,

要么就是最終連到了一個\(0-0\),此時開頭和結尾都是\(0-0\)

那么,現在就是一堆\(0-0\)鏈連成環的方案數了。這個答案現在還是第一類斯特林數。

但是因為\(0-0\)邊沒有確定的起點或者重點,因此還需要額外乘上一個階乘。

代碼戳這里

T2.girls

題意

求所有滿足條件的三元組\((i,j,k)\)的貢獻\(A\times i+B\times j+C\times k\),其中\(i\lt j\lt k\)

其中有\(m\)個限制\((u,v)\),表示\(u,v\)不能同時選。

題解

我們把選擇出來的東西看做點,限制叫做邊。

考慮容斥,首先我們計算任選三個點的方案數,然后減去選擇了一條邊然后另外一個點任選的貢獻。

再把選擇了兩條邊的貢獻加回來,再減去三元環的貢獻。

前面都只需要枚舉邊或者枚舉點就好了,都可以做到線性的復雜度。

三元環的求法比較有趣,

我們把所有的邊強制定向,由度數大的連向度數小的,度數相等按照編號連。

這樣子我們暴力枚舉一條邊,然后就確定了兩個點。

把其中一個點的所有出邊到達的點打個標記,再檢查一下另外一個點是否有標記就好了。

這樣的復雜度?

這樣連完邊后,每個點的出度都不會超過\(\sqrt m\)

證明?

我們的點分成了兩類,一類是度數小於\(\sqrt m\)的,另外一類是大於\(\sqrt m\)的,其中\(m\)是邊數。

對於一個度數小於\(\sqrt m\)的點,它的度數本來就不超過\(\sqrt m\),那么定向后也不會大於\(\sqrt m\)

對於一個度數大於\(\sqrt m\)的點,它的所有出邊都連向度數大於\(\sqrt m\)的點,

因為邊的總數是固定的,所以這樣的點的個數不會大於\(\sqrt m\)

所以總的復雜度不超過\(O(m\sqrt m)\)

代碼戳這里

T3

題意

給定\(n\)個字符串,要求在線支持以下操作

在一個字符串后面添加一個字符。

詢問第\(y\)次操作之后的一個串\(x\),在當前的串\(z\)中出現的次數。

詢問當前所有串的本質不同的子串個數。

詢問一個串\(T\)在所有給定的串中出現的次數的最大值。

題解

留坑

總結

沒有多少天了。希望能夠找到自己狀態吧。最近的題目都有點不是很可做。(對我而言)

導致考場上並沒有那么認真的思考,希望接下來的題目能夠回歸正常吧。

Day7

我很想知道今天的題目來自誰。

壓縮包鏈接 密碼: j2r9

流水賬

沒什么好說的,毒瘤題\(\times \infty\)

不全的題解

T1.inkmaster

題意

給定一個仙人掌,每個點可以染一種顏色,每條邊對應的兩個點的顏色不能相同。

多次詢問,每次告訴你有多少種顏色,問染色的方案數。

題解

考慮一棵樹的貢獻,從上往下考慮,顯然對於每個點有影響的點有且僅有父親

所以每個點的顏色只是不能與父親相同,所以答案是\(C\times(C-1)^{n-1}\)

現在回歸仙人掌。顯然對於答案有影響的從只有父親,

變成了對於返祖邊的終點,還有求與這個環的最底端顏色不同。

那么,如果這個環的顏色確定了,對於其它的環也沒有任何影響。

所以我們把所有的環全部找出來計算。

因為大小相同的環本質上是一樣的,所以可以開桶記錄所有的環的大小。

每次計算一下環的貢獻,最后全部乘起來就行了。

考慮一個環的貢獻,我們斷環成鏈,貢獻是\(C\times(C-1)^{n-1}\)

減去首尾顏色相同的貢獻,也就是\(C\times (C-1)^{n-2}\)

這個時候,我們可以把頭尾縮起來,看成一個點,但是這個時候似乎又多計算了一些東西。

所以我們這里相當於是一個容斥。並且貢獻是一個等差數列,可以快速冪\(log\)算。

因為長度不同的環的個數最多不會超過\(\sqrt n\)個,

所以每次詢問的復雜度就是\(O(\sqrt n\ log n)\)

總復雜度\(O(q\sqrt n\ logn)\)

代碼戳這里

T2.branching

題意

給定一棵樹,有兩種走法,一種是隨機選擇一個點並移動過去,另外一種是沿着一條邊走。

求從點\(u\)到達\(v\)的最短步數的期望。

題解

每個點到達目標點的走法一定是先隨機若干次,到了一個比較優秀的點的時候就直接走過去。

那么,這個東西顯然有一個閥值,如果一個點距離目標點的距離大於閥值則繼續隨機換點。

現在考慮如何求解這個閥值。考慮二分,我們假設二分值為\(x\)

那么有:$$x=1+\frac{\sum min(dis,x)}{n}$$

那么現在的問題就是求出到達所有點的\(dis\)了。

這個東西可以用動態點分治進行計算,時間復雜度是\(O(nlog^3n)\),聽說可以做到兩個\(log\)

還有一種比較玄學的做法,考慮一下最大的答案,這個答案一定在一條鏈上,並且目標點是一個端點。

那么打表可以得到,在本題的數據范圍內,最大的答案不會超過\(500\)

那么可以預處理出距離每個點距離不超過\(500\)的所有點的距離和,這樣就可以直接算了。

代碼戳這里

T3.euclid

題意

給定兩個矩陣,求$$\sum_{x=1}^LA^xB^{\frac{Px+r}{Q}}$$

題解

留坑。

總結

題目越來越毒瘤了。總結也越來越短了。因為我也不知道可以寫什么了。

Day8

今天的題目來自於一中。

壓縮包鏈接 密碼:rgjn

考試的五個小時

上來先把題看了一遍,\(T1\)一眼會\(75\)分,\(T2\)題面好長,先跳了。

\(T3\)???這不是傻逼題嗎?為什么數據范圍這么小?

這不是個傻逼題嗎?我不會看錯題了吧。

真的沒看錯?那就是道傻逼題。。。。。

寫完過了大樣例,非常自信,順帶自己\(yy\)一下,這題做\(10^6\)都隨便做啊。。

\(T1\)想了想正解,發現沒有思路,怎么算復雜度都是假的。

所以暴力\(AC\)自動機+線段樹維護矩陣(一臉我出的那題的感覺),順手碼完\(75\)分。

回頭看\(T2\),順手退火了,各種調參什么的過了樣例。

然后就開了幾局空當接龍。

期望得分\(75+?+100=?\)

實際得分\(65+8+100=173\)

聽說\(T2\)直接\(return\)就過了,\(SPJ\)好迷啊。

\(T1\)正解是把\(AC\)自動機上被標記的點全部刪去再向我那么做?

我懷疑我會分分鍾把\(std\)卡掉,這復雜度顯然是假的啊。。

題解

T1.kill

題意

給定一個二進制串,一些位置已經給出,其它位置隨便填。

給定若干個不合法的模板串,每次詢問一個區間\([L,R]\)能夠組成的所有串中,合法串的總數。

同時支持單點修改位置是給定還是任意。

題解

先構建\(AC\)自動機,然后顯然是每次在上面\(dp\)

這個過程我們肯定不能每次都模擬一遍,所以把轉移壓進矩陣。

有一些冗雜的值不需要存進矩陣,就是那些不合法的\(AC\)自動機上的狀態。

然后用線段樹快速維護一下矩陣乘法就好了,時間復雜度\(O(nlogn|S|^3)\)

代碼戳這里

T2.politics

因為有點假,所以就自己看吧。

T3.eat

題意

給定\(n\)個集合,所有集合元素個數的並不超過\(m\),每個元素選或者不選都可以得到一個權值,

求任選\(k\)個集合的交的權值的期望。

題解

題目逗逼了。

直接分開考慮每個元素,算一下它的出現次數就好了。

時間復雜度\(O(\sum|S|+m)\),復雜度瓶頸在於讀入。

然而這題可以改一下,更改為給定所有由這些元素構成的集合的權值,求期望。

這樣子只是把求每個位出現的次數變成了計算每個交出現的次數。

那么,我們容斥計算就好了。

先計算出選擇當前集合\(S\)的子集的方案數,再用它的子集去減掉就好了。

這個過程就是\(FWT\)的過程。

本題的代碼

總結

今天的題目很多鍋,所以我的總結都越來越短了。

Day9

今天的題目來自於衡八。

壓縮包地址 密碼:iptz

Test

看了一遍題目,感覺好難。

忽然覺得\(T2\)我會做\(m=1\)\(2\)的特殊情況。

於是就寫了一下。

忽然發現自己會這道題目了,只需要先枚舉一下左右的顏色個數,再用組合數算方案就好了。

然后\(T1\)\(T3\)寫完暴力就滾粗了。

題解

T1.circle

題意

給定一個競賽圖,欽定其中\(K\)個點,回答在這\(K\)個點以外,最少去掉多少個點使得圖不存在環

題解

留坑。

T2.color

題意

給定一個\(n\times m\)的矩陣以及\(K\)中顏色,可以任意染色。

要求改矩陣從任意列分開,左右兩塊包含的顏色數相同,求染色方案數。

題解

顯然左右兩列的顏色數量相同,中間染的顏色一定是兩側顏色的交。

那么枚舉用了幾種顏色\(a\),以及兩側顏色的交\(b\)

那么,此時貢獻的方案數就是從\(K\)種顏色中選出\(a+a-b\)個,

此時選擇顏色的方案數是\(C_k^b\times C_{k-b}^{a-b}\times C_{k-a}^{a-b}\)

然后考慮左右染色的方案數,顯然是把\(n\)個格子染成\(a\)中顏色,

這個方案數是第二類斯特林數乘上階乘,中間的格子用快速冪算就可以了。

代碼戳這里

T3.simulate

題意

給定一個由\(012\)組成的數組。

每次都將大於等於而的所有數減去二,然后其左右兩側的數各加上一。

當沒有大於等於二的數時停止,求終止的數列。

題解

留坑。

總結

\(Last\ Day\),結束了。

這段時間犯了各種各樣的奇奇怪股的錯誤,這個是真的很不應該。

從另外一個方面來說,這段時間也接觸到了很多有趣的東西。

總而言之,收獲還是有的吧。

當然,現在我非常想睡上一天了。


免責聲明!

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



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