1. 程式人生 > >牛客國慶集訓派對Day6——題解

牛客國慶集訓派對Day6——題解

A Birthday

    思路:考慮費用流時把每個part拆成nn個點,選擇第ii個點的代表為放置ii塊蛋糕和(i1)(i - 1)塊蛋糕的時間差,這個時間差是遞增的,因此在費用流的過程中必定會從小到大選擇
    具體建圖:左邊nn個點代表nn個蛋糕,右邊mnm * n個點代表mm個part,每個part拆成nn個點。源點向每個左邊的點連一條流量11費用00的邊,每個右邊的點向匯點連一條流量11費用00的編。每個蛋糕向可以放的兩個part的所有點連邊,連向第ii個點的費用為i2(i1)2i^2 - (i - 1)^2,流量為11。這樣求最小費用流既為答案。

B Board

    把格子NN染色,第ii行第jj列格子的顏色為(i+j)(i + j) % NN。那麼每次操作時,必定是NN種不同的顏色都有一格被操作到,因此最後任何顏色格子的和必定是相等的。因此只需要記錄每種顏色格子的和,並算出缺失格子的顏色C,用其餘顏色的和減去顏色C的和即可

C Circle

    因為(i,i+1)=1(i,i+1)=1(1,n)=1(1,n)=1,所以把1...n1...n依次放進一個環,就可以啦。答案為nn

D 土龍弟弟

    下面會有一些定義。出此題是期望比賽的時候大家憑感覺得到結論,不證明。
    首先題目問的是在torus上扣若干個洞,所得曲面上的閉環的同倫等價類。(定義:torus:就是我們定義的地圖,形似甜甜圈。閉環:就是說土龍弟弟一天走的路徑。因為會回來所以叫閉環。同倫等價類:就是一個土龍弟弟的路線可能會變換。凡是可能屬於同一個土龍弟弟的兩條路線就是相互同倫的。題目問的就是最少能分成多少組使得組內相互同倫。)
    我們把扣掉的洞用線連起來,使得線之間不相交且按照線將曲面分割成若干簡單的部分。(簡單的部分:就是這一部分是你在紙上隨便畫個不自交的閉環得到的東西。簡單是因為這一個區域中所有的閉環都同倫,因為可以縮小到很小再移動到一起。)
    分割區域這一步需要小構造一下。大體思路就是每一行都畫一條橫的線,這線實際會被洞分割成多條線。然後有些區域是個環(即從左邊走到最右邊再向右回到最左邊),即並非簡單區域。這些區域再畫一條豎線。

    這樣分割後,一個閉環就可以用依次穿過的線的編號組成的字串來表示(除了記錄哪條線,方向也有用。並且由於是環,字串也是迴圈的。)然後消去相鄰相反括號(即連續的正穿和反穿同一條線的部分。因為每個區域都是簡單的,所以連續正穿和反穿中間的部分可以不斷收縮直到不穿過這條線,所以消去後所得的曲線和之前是同倫的。)最後為了判斷迴圈串相等要用最小表示法。
    證明:我們要證的是同倫當且僅當消去相鄰相反括號後的序列迴圈相等。
    假設a經過消括號得到(不能再消的)bb,顯然a和b是同倫的,因為每一步都同倫。假設aa'消括號得到bb'。如果bbb

b'迴圈相等,a和b同倫。這就證明了一半。反過來,對一個曲線做同倫變換時,只能產生或消除相鄰的相反括號。所以如果bbbb'不等,他們又都沒有相鄰相反括號可以消去,它們就不可能通過產生和消除相鄰相反括號相互轉換,即bbbb'不同倫,即aaaa'不可能同倫。

    最後注意沒有洞是特殊情況。題面裡除去了這種情況。其實torus上扣若干洞後的基本群總是free group,但是沒扣洞時的基本群是Z2Z^2(平面整數格點加法群)。

E Growth

把獎勵的xx拿出來從小到大排序,得到x1,x2,...,xnx_1,x_2,...,x_n
把獎勵的yy拿出來從小到大排序,得到y1,y2,...,yny_1,y_2,...,y_n
v[i][j]v[i][j] 表示aa值到達xix_ibb值達到yiy_i時接下來每天可以得到的獎勵。
v[i][j]=v[i1][j]+v[i][j1]v[i1][j1]+t[i][j]v[i][j] = v[i - 1][j] + v[i][j - 1] - v[i - 1][j - 1] + t[i][j]
其中 t[i][j]t[i][j] 為滿足x=iy=jx=i,y=j的獎勵的總和。
f[i][j]f[i][j] 表示aa值達到xix_ibb值達到yjy_j時已經拿到的獎勵的最大值。
f[i][j]+(x[i+1]x[i]1)t[i][j]+t[i+1][j]>f[i+1][j]f[i][j] + (x[i + 1] - x[i] - 1) * t[i][j] + t[i + 1][j] -> f[i + 1][j]
f[i][j]+(y[j+1]y[j]1)t[i][j]+t[i][j+1]>f[i][j+1]f[i][j] + (y[j + 1] - y[j] - 1) * t[i][j] + t[i][j + 1] -> f[i][j + 1]
最後統計一下答案就可以了。

F kingdom

    f[i]f[i]代表ii個點時的答案,g[i][j]g[i][j]代表若干顆樹加起來,sizesize和為ii,每棵樹size<=jsize<=j時,這些樹的代價和最大是多少
    從11nn列舉ii,在ii固定時列舉心腹的影響力大小更新f[i]f[i],然後用類似揹包的思路更新g[i][1]g[i][i]g[i][1]~g[i][i]
    複雜度O(N2)O(N^2)

G Matrix

    ww個格子的重心的座標為xiwiwi,yiwiwi)(\frac{∑x_iw_i}{∑w_i}, \frac{∑y_iw_i}{∑w_i})
    那麼其實我們只要維護xiwiyiwiwi∑x_iw_i,∑y_iw_i,∑w_i就可以了。
    假設我們現在有一個頂點為(x,y)(x, y)的三角形,我們想要推到頂點為(x,y+1)(x, y+1)的三角形,觀察兩者之間的差異,會發現在推過去的過程中,其實就是刪去了一個斜條,又加入了一個斜條。
    同理,從(x,y)(x, y)(x+1,y)(x+1, y)其實只是刪去了兩個斜條,加上了底上的橫條,而這些關鍵的值都是可以通過字首和的方法維護。

H Mountain

    考慮山中最高的一座,最優操作一定是從第一座山的左下角開始不停地往上爬,然後從最高的山不停地往下爬爬到最後一座山的右下角。
    所以答案為最高山的高度2*2

I 清明夢超能力者黃YY

    首先每條路徑從LCA處分開可以拆成兩條鏈
    假設鏈A>BA->B執行了第ii次染色操作,假設AABB的祖先,那麼我們在BB點加入一個"插入ii"的事件,在AA的父親點加入一個"刪除i"的事件
    然後dfsdfs整顆樹求解,每個點維護一個線段樹。處理一個點時先合併所有兒子的線段樹,然後再處理這個點上的事件,得到線段樹之後詢問第KK大值既可得到答案。
    複雜度分析:

Node* merge(Node* a, Node* b) {
    if (a == NULL) return b;
    if (b == NULL) return a;
    a->sum += b->sum;
    a->child[0] = merge(a->child[0], b->child[0]);
    a->child[1] = merge(a->child[1], b->child[1]);
    return a;
}

    考慮以上的線段樹合併,每次合併會減少一個區間。而在事件點插入、刪除的時候會產生至多loglog個區間,因此複雜度為