這場題目設置有點問題啊,難度:Div.2 A->Div.2 B->Div.2 D->Div.2 C->Div.2 D->Div.1 D-> Div.1 E->Div.1 F簡直有毒
只AC 4題似乎就是1000+名了
這種考驗手速的時刻Itst就比較擅長了,然后就紅名+拿衣服了……
A. Ilya and a Colorful Walk
如果最左邊和最右邊不同就是\(N-1\),否則就是中間跟兩邊顏色不同的塊到兩邊距離的最大值
B. Alyona and a Narrow Fridge
二分答案,對於一個二分值\(mid\)將所有要放的牛奶拿出來,每一次最高的和次高的放在一層
C. Ramesses and Corner Inversion
注意到對任意\(x \times y\)的矩形做一次操作,等價於對這個矩形內所有\(2 \times 2\)的子矩形做一次操作,於是我們只需要對\(2 \times 2\)的矩形做操作就可以了,這個直接從左往右、從上往下、要翻轉就翻轉就可以了
D. Frets On Fire
題目相當於要求:有\(n\)條線段,左端點為\(s_i\);\(q\)組詢問,每一組詢問每條線段的長度都為\(l\),問線段覆蓋總長度
設\(s_{i+1} = INF\),那么答案就是\(\sum\limits_{i=1}^n \min\{s_{i+1} - s_i , l\}\)。把所有\(s_{i+1}-s_i\)存下來排個序,每一次詢問時二分
E. Pavel and Triangles
顯然每一次選出的三角形的邊長一定是\((2^i,2^i,2^j)\),其中\(j \leq i\)。所以可以從小往大貪心,每一次選擇盡可能多的三角形,即先把\(< i\)的剩下的木棒盡可能地用掉,然后再3個3個地取當前剩余的木棒
F. Niyaz and Small Degrees
先考慮對於一個\(x\)求答案。考慮樹形DP。
設\(val_u\)表示\(u\)到它父親的邊的權值,設\(f_{u , flag = 0/1}\)表示對於\(u\)子樹內的點除\(u\)以外度數都不超過\(x\),且\(u\)的度數不超過\(x+flag\)時的最小代價。
轉移考慮:對於一個點\(v\),假設它的度數為\(d_v(d_v > x)\),那么轉移到\(f_{v,1}\)的狀態中需要切掉\(v\)與其孩子的\(d_v - x - 1\)條邊,而轉移到\(f_{v,0}\)需要切掉\(d_v - x\)條邊。而對於\(y \in ch_v\),切掉邊\((y,v)\)意味着\(f_v\)從\(f_{y,1}+val_y\)轉移,否則從\(f_{y,0}\)轉移。所以初始默認答案為\(\sum\limits_{y \in ch_v} f_{y,0}\),對於所有孩子按照\(f_{y,1}+val_y-f_{y,0}\)從小到大排序,選擇前面若干條邊切掉進行轉移。
然后可以發現:\(\sum\limits_{i=1}^n d_i = 2(n-1)\)即\(\sum\limits_{i=0}^{n-1}\sum\limits_{j=1}^n [d_i > j] = 2(n-1)\)。所以如果稱某一次詢問中必須要切掉相鄰的若干條邊的點為重要點,則在所有詢問中,重要點的總和為\(2(n-1)\)。
到這里不難想到虛樹。對於每一次詢問建立虛樹。因為虛樹上無法體現重要點與非重要點之間的邊,但是實際有可能會切掉這樣的邊,所以對於每一個重要點用一個堆維護它和它非重要點孩子之間的邊的邊權。DP過程中,如果某個點\(x\)與虛樹上\(x\)的孩子\(y\)在原樹上的距離超過\(2\),則直接用\(\min(f_{y,0} , f_{y,1} + val_y)\)轉移\(f_x\),否則像上面一樣先默認轉移\(f_{y,0}\),然后把\(f_{y,1} + val_y - f_{y,0}\)丟進堆里,用堆求前若干小轉移到\(f_{x,0}\)和\(f_{x,1}\)。
將詢問從小到大做,就可以直接維護每個重要點的非重要點兒子的堆。
Update:關於priority_queue,它的賦值操作似乎跟元素個數有關(但是非常快?),大力賦值在菊花圖上會TLE,所以要用multiset對操作進行撤銷。
G. Get Ready for the Battle
答案的下界是\(\lceil \frac{\sum\limits_{i=1}^m hp_i}{n} \rceil\),而構造題一般都會取到這個下界(要不然怎么構造啊喂),所以考慮構造一種方式使得總攻擊次數達到下界。那么我們需要盡可能少地浪費兵力,也就是說要盡可能把所有敵人打到\(0\)血。
為了構造的方便,我們令攻擊方式為:先所有軍隊一起攻擊第一個敵人,當第一個敵人的血量\(<n\)時,讓一個前綴的軍隊攻擊第一個敵人,讓第一個敵人恰好達到\(0\)血,剩下的軍隊直接去攻擊第二個敵人。維護前綴和\(sum_i\),也就是說對於\(\forall i \in[1,m)\),要存在一個前綴的軍隊,它們的人數之和為\(sum_i \mod n\)。不難想到一種可行方案:將所有\(sum_i \mod n\)排序得到數組\(b_i\),\(b_0 = 0 , b_m = n\),則\(s_ i = b_i - b_{i-1}\)。
構造方案直接暴力模擬上面的攻擊方法。
H. Triple
一個暴力是\(O(n2^kk)\)的FWT,顯然跑不過
顯然地,對於三元組\(A,B,C\),將其變為\(0,A \oplus B , A \oplus C\),把最后結果的下標異或上\(A\),這兩者得到的結果等價。
那么在初始的數組中,\(F_0 = a , F_{A \oplus B} = b , F_{A \oplus C} = c\),FWT之后每個位置一定會是\(a+b+c,a+b-c,a-b+c,a-b-c\)中的一個。
設暴力FWT之后全部乘起來得到的某個位置的值為\((a+b+c)^x(a+b-c)^y(a-b+c)^z(a-b-c)^w\),解出\(x,y,z,w\)就可求出FWT結果。
首先\(x+y+z+w=n\),然后任意給\((a,b,c)\)賦值不會改變\(x,y,z,w\)的值,那么令\((a,b,c) = (0,1,0)\),將得到的\(F\)數組加起來FWT。因為FWT的和等於和的FWT,故有\((a+b+c)x + (a+b-c)y + (a-b+c)z + (a-b-c)w = p\),其中\(p\)就是FWT后得到的當前位置的值。對於\((a,b,c) = (0,0,1)\)也做一遍。
現在有了\(3\)個方程,但\((a,b,c)=(1,0,0)(0,1,0)(0,0,1)\)都出現過了,再取\((a,b,c)\)都和這三個向量線性相關,所以要換一種思路。考慮數組\(G\),\(G[x] = \sum\limits_{i=1}^n [B_i \oplus C_i = x]\),對這個數組FWT,可以得到\(x-y-z+w=q\),其中\(q\)是FWT完成之后的點值表示。
原因大概是:設序列\(F\)FWT后的序列為\(F'\),那么\(F[b]\)對\(F'[a]\)的貢獻的系數是\((-1)^{count(a \& b)}\),其中\(count(x) = x\)在二進制下\(1\)的個數,這個可以由FWT的式子得到。如果第\(i\)個三元組FWT之后第\(j\)位的值為\(a-b+c\),那么有\(2 \not\mid count((A \oplus B) \& j) , 2 \mid count((A \oplus C) \& j)\),即\(2 \not\mid count((B \oplus C) \& j)\),那么\(F[B \oplus C]\)對\(F'[j]\)的貢獻就是\(-1\),其余同理。
那么現在得到了\(4\)個方程組,可以求出點值表示,最后IFWT一下。
BONUS:可以利用與上面類似的方法解決更一般的對於\(m\)元組、\(A,B,C < 2^k\)的問題,復雜度約為\(O(2^{m+k}(m+k)+nm)\)。