C - Make Good
记 s u m sum sum为所有数的异或和, t o t tot tot为所有数的和。 t o t tot tot显然必须是偶数。所以如果 t o t tot tot是奇数的话,就先往数组里面加入一个 1 1 1。
如果 2 × s u m > t o t 2\times sum > tot 2×sum>tot,就往数组里面加入两个 2 × s u m − t o t 2 {2\times sum - tot \over 2} 22×sum−tot,这对数组中的数的异或和没有影响。
否则,先加入一个 2 58 2^{58} 258(一个很大的 2 2 2的整数次幂),然后就会转化成 2 × s u m > t o t 2\times sum > tot 2×sum>tot的情况。
如果又要加入 1 1 1又要加入 2 58 2^{58} 258,可以直接加入数 1 + 2 58 1+2^{58} 1+258,这样就可以满足加的数至多是三个的限制。
D - Strange Device
首先考虑 k = n − 1 k=n-1 k=n−1怎么做:可以把每个大小为 n − 1 n-1 n−1的子集都问一遍,这样第 m + 1 m+1 m+1小的会出现 m m m次,第 m m m小的会出现 n − m n-m n−m次,根据出现过的元素的大小关系以及它们分别的出现次数就可以推出 m m m。
当 n > k + 1 n>k+1 n>k+1,直接对前 k + 1 k+1 k+1个元素通过上面的方法计算就可以了。
E - Divide Points
将点分成四组: A 0 , 0 , A 0 , 1 , A 1 , 0 , A 1 , 1 A_{0,0},A_{0,1},A_{1,0},A_{1,1} A0,0,A0,1,A1,0,A1,1。点 ( x , y ) (x,y) (x,y)属于组 A x ( m o d 2 ) , y ( m o d 2 ) A_{x\pmod 2,y\pmod 2} Ax(mod2),y(mod2)。用 P , Q P,Q P,Q代表最后分得的两个点集。
若所有点都属于同一个组,则将所有点的坐标除以 2 2 2(如果原数是奇数,则向下取整)之后再做,与原问题等价。
如果 A 0 , 0 ∪ A 1 , 1 A_{0,0}\cup A_{1,1} A0,0∪A1,1非空,且 A 0 , 1 ∪ A 1 , 0 A_{0,1}\cup A_{1,0} A0,1∪A1,0非空,令 P = A 0 , 0 ∪ A 1 , 1 , Q = A 0 , 1 ∪ A 1 , 0 P=A_{0,0}\cup A_{1,1},Q=A_{0,1}\cup A_{1,0} P=A0,0∪A1,1,Q=A0,1∪A1,0即可。【同一组内的点的 ( x + y ) m o d 2 (x+y)\bmod 2 (x+y)mod2相同】
否则,若 A 0 , 0 ∪ A 1 , 1 A_{0,0}\cup A_{1,1} A0,0∪A1,1为空集,令 P = A 0 , 1 , Q = A 1 , 0 P=A_{0,1},Q=A_{1,0} P=A0,1,Q=A1,0即可。【只有同一组内的点的 ( x 1 − x 2 ) 2 + ( y 1 − y 2 ) 2 (x_1-x_2)^2 + (y_1-y_2)^2 (x1−x2)2+(y1−y2)2是 4 4 4的倍数】
否则 A 0 , 1 ∪ A 1 , 0 A_{0,1}\cup A_{1,0} A0,1∪A1,0为空集,令 P = A 0 , 0 , Q = A 1 , 1 P=A_{0,0},Q=A_{1,1} P=A0,0,Q=A1,1。【同上】
F - Awesome Substrings
设 x = L c n t x = {L\over cnt} x=cntL,其中 L L L表示子串的长度, c n t cnt cnt表示子串内 1 1 1的个数。设 T T T为某个定值。
设 a i = ∑ j ≤ i [ s j = 1 ] a_i = \sum_{j\le i} [s_j = 1] ai=∑j≤i[sj=1]。
将答案分为两部分计算;
- x ≤ T x\le T x≤T:枚举每一个 x x x,然后枚举子串右端点 r r r,则左端点应满足 r − ( l − 1 ) a r − a l − 1 = x ⇒ r − a r x = l − 1 − a l − 1 x {r-(l-1)\over a_r-a_{l-1}} = x\Rightarrow r-a_rx = l-1-a_{l-1}x ar−al−1r−(l−1)=x⇒r−arx=l−1−al−1x,直接用map或者hash_table统计一下即可。
- x > T x> T x>T,显然有 c n t = L x ≤ n T cnt = {L\over x} \le {n\over T} cnt=xL≤Tn,所以可以枚举子串的左端点和 c n t cnt cnt,此时要求右端点必须落在某个区间内且 r − l + 1 ( m o d c n t ) r-l+1 \pmod {cnt} r−l+1(modcnt)为 0 0 0,可以 O ( 1 ) O(1) O(1)计算这样的右端点的数量。
如果用map,时间复杂度 O ( n T log n + n ⋅ n T ) O(nT\log n + n\cdot {n \over T}) O(nTlogn+n⋅Tn),当 T T T取 n log n {\sqrt{n\over \log n}} lognn的时候复杂度最优,为 O ( n n log n ) O(n\sqrt {n\log n}) O(nnlogn)。
G - Subset with Zero Sum
Sol
i − n ≤ a i ≤ i − 1 i-n\le a_i \le i-1 i−n≤ai≤i−1等价于 1 ≤ i − a i ≤ n 1\le i - a_i \le n 1≤i−ai≤n。
令 i i i向 i − a i i-a_i i−ai连边,会得到基环内向树森林。取一个环上的所有元素:
x − a x = y y − a y = z ⋮ u − a u = x x - a_x = y \\ y - a_y = z \\ \vdots \\ u - a_u = x x−ax=yy−ay=z⋮u−au=x
将所有式子加起来,会得到 a x + a y + ⋯ a u = 0 a_x+a_y+\cdots a_u = 0 ax+ay+⋯au=0。