整体来说我的表现很差,经常卡题 (做不出来或者调半天),拿成绩主要还是靠着西电大区优秀的匹配机制 (以及土豆摆烂)。
给定正整数组成的序列 { b i } \{b_i\}{ b i } ,求
1 ≤ l ≤ i 1 < i 2 < i 3 ≤ r ≤ ∣ { b i } ∣ b i 1 + b i 2 + b i 3 − ( r − l ) \max_{1 \leq l \leq i_1 < i_2 < i_3 \leq r \leq |\{b_i\}|} b_{i_1} + b_{i_2} + b_{i_3} - (r - l)
1 ≤ l ≤ i 1 < i 2 < i 3 ≤ r ≤ ∣ { b i } ∣ max b i 1 + b i 2 + b i 3 − ( r − l )
显然取 l = i 1 l = i_1l = i 1 ,r = i 3 r = i_3r = i 3 一定不会使得答案更差,所以可以把答案改写成
1 ≤ i 1 < i 2 < i 3 ≤ ∣ { b i } ∣ ( b i 1 − i 1 ) + b i 2 + ( b i 3 + i 3 ) \max_{1 \leq i_1 < i_2 < i_3 \leq |\{b_i\}|} (b_{i_1} - i_1) + b_{i_2} + (b_{i_3} + i_3)
1 ≤ i 1 < i 2 < i 3 ≤ ∣ { b i } ∣ max ( b i 1 − i 1 ) + b i 2 + ( b i 3 + i 3 )
这样就是个经典的“多阶段决策最优化问题”,可以 DP:用 f x ( i ) f_x(i)f x ( i ) 表示前 i ii 个数,取了 x xx 个 { i k } \{i_k\}{ i k } 值的最优解,则
f 1 ( i ) = max ( f 1 ( i − 1 ) − 1 , b i ) f 2 ( i ) = max ( f 2 ( i − 1 ) − 1 , f 1 ( i − 1 ) − 1 + b i ) f 3 ( i ) = max ( f 3 ( i − 1 ) , f 2 ( i − 1 ) − 1 + b i ) f_1(i) = \max(f_1(i - 1) - 1, b_i) \\
f_2(i) = \max(f_2(i - 1) - 1, f_1(i - 1) - 1 + b_i) \\
f_3(i) = \max(f_3(i - 1), f_2(i - 1) - 1 + b_i)f 1 ( i ) = max ( f 1 ( i − 1 ) − 1 , b i ) f 2 ( i ) = max ( f 2 ( i − 1 ) − 1 , f 1 ( i − 1 ) − 1 + b i ) f 3 ( i ) = max ( f 3 ( i − 1 ) , f 2 ( i − 1 ) − 1 + b i )
答案就是 f 3 ( ∣ { b i } ∣ ) f_3(|\{b_i\}|)f 3 ( ∣ { b i } ∣ ) 。时间复杂度是 O ( n ) \mathcal{O}(n)O ( n ) ,空间复杂度每次对 x xx 倒序求 (类似 0-1 背包) 就能做到 O ( 1 ) \mathcal{O}(1)O ( 1 ) 。
交互题。每次可以询问一个整数,对方会告诉你这个数是大于,小于,还是等于答案 (保证答案是不超过 m mm 的正整数)。但是对方会周期性地反向回答 (即把大于说成小于,小于说成大于):对于第 i ii 次提问,如果 p i n p_{i \bmod n}p i m o d n 是 1 11 ,就会反向回答。要求用不超过 60 606 0 次提问确定答案。n nn 和 m mm 都已知,1 ≤ n ≤ 1 0 9 1 \leq n \leq 10^91 ≤ n ≤ 1 0 9 ,1 ≤ m ≤ 30 1 \leq m \leq 301 ≤ m ≤ 3 0 。
直接问 n nn 次 1 11 ,如果答案等于 1 11 的话第一次问完就直接退出,否则答案必然大于 1 11 ,所以就能看出对方是不是在反向回答。这样就能直接把 { p i } \{p_i\}{ p i } 全问出来。然后二分查找就行了……
这题十分甚至九分地无聊。
给定整数序列 { a i } \{a_i\}{ a i } ,进行若干次操作,第一种操作给定 l , r , x l, r, xl , r , x ,询问能否选出 { a l , ⋯ , a r } \{a_l, \cdots, a_r\}{ a l , ⋯ , a r } 并修改其中一个元素,使它们的最大公约数为 x xx ;第二种操作给定整数 i , y i, yi , y ,将 a i a_ia i 修改为 y yy 。0 < a i ≤ 1 0 9 0 < a_i \leq 10^90 < a i ≤ 1 0 9 ,∣ { a i } ∣ ≤ 5 × 1 0 5 |\{a_i\}| \leq 5 \times 10^5∣ { a i } ∣ ≤ 5 × 1 0 5 ,询问次数不超过 4 × 1 0 5 4 \times 10^54 × 1 0 5 。
容易看出如果 x ∣ g c d ( a l , ⋯ , a r ) x \mid gcd(a_l, \cdots, a_r)x ∣ g c d ( a l , ⋯ , a r ) ,那么随便选一个元素修改成 x xx 就行了。否则存在一个最小的 k kk 使得 l ≤ k ≤ r l \leq k \leq rl ≤ k ≤ r ,x ∤ g c d ( a l , ⋯ , a k ) x \nmid gcd(a_l, \cdots, a_k)x ∤ g c d ( a l , ⋯ , a k ) ,可以通过弄一个线段树维护区间 gcd 然后在线段树上二分查找求出 k kk 。这样考虑把 a k a_ka k 修改成 x xx ,然后再查询 g c d ( a k + 1 , ⋯ , a r ) gcd(a_{k + 1}, \cdots, a_r)g c d ( a k + 1 , ⋯ , a r ) 是否被 x xx 整除即可。
这样的时间复杂度是 O ( ( n + q log n ) log max a i ) \mathcal{O}((n + q \log n) \log \max a_i)O ( ( n + q log n ) log max a i ) ,注意不能把线段树上二分写成二分套线段树查询,否则时间复杂度会变成 O ( ( n + q ( log n ) 2 ) log max a i ) \mathcal{O}((n + q (\log n)^2) \log \max a_i)O ( ( n + q ( log n ) 2 ) log max a i ) 而超时。
比赛的时候 latato 选手搁那摆烂,在注释里面用自然语言打出了算法,然后打出“但是我不想写”,结果输了。
给定整数序列 { a i } , { b i } \{a_i\}, \{b_i\}{ a i } , { b i } 和数 p pp ,求有多少下标 q qq 满足 { a q , a q + p , a q + 2 p , ⋯ , a q + ( ∣ { b i } ∣ − 1 ) p } \{a_q, a_{q+p}, a_{q+2p}, \cdots, a_{q+(|\{b_i\}|-1)p}\}{ a q , a q + p , a q + 2 p , ⋯ , a q + ( ∣ { b i } ∣ − 1 ) p } 重新排列能得到 { b i } \{b_i\}{ b i } 。1 ≤ ∣ { a i } ∣ , ∣ { b i } ∣ , p ≤ 2 × 1 0 5 1 \leq |\{a_i\}|, |\{b_i\}|, p \leq 2 \times 10^51 ≤ ∣ { a i } ∣ , ∣ { b i } ∣ , p ≤ 2 × 1 0 5 。
先把所有下标 1 , 2 , ⋯ , ∣ { a i } ∣ 1, 2, \cdots, |\{a_i\}|1 , 2 , ⋯ , ∣ { a i } ∣ 按对 p pp 的模分类,然后我们发现从 p = x p = xp = x 变到 p = x + q p = x + qp = x + q 只会删除一个元素 a x a_xa x ,再增加一个元素 a x + ∣ { b i } ∣ p a_{x + |\{b_i\}|p}a x + ∣ { b i } ∣ p 。这样用一个 std::map
维护一下元素值的出现次数,和 { b i } \{b_i\}{ b i } 中所有元素的出现次数比较就行了。但是比较两个 std::map
最坏是线性时间复杂度的,所以要进一步维护一下出现次数不正确的元素的个数,这样次数不正确的元素个数为 0 00 就说明是一个合法解。
因为数据出水了,所以强行比较两个 std::map
能过,可以用数据 { a i } = { 1 , 2 , ⋯ , 1 0 5 , 1 , 2 , ⋯ , 1 0 5 } \{a_i\} = \{1, 2, \cdots, 10^5, 1, 2, \cdots, 10^5\}{ a i } = { 1 , 2 , ⋯ , 1 0 5 , 1 , 2 , ⋯ , 1 0 5 } , { b i } = { 1 , 2 , ⋯ , 1 0 5 } \{b_i\} = \{1, 2, \cdots, 10^5\}{ b i } = { 1 , 2 , ⋯ , 1 0 5 } , p = 1 p = 1p = 1 卡掉。
有一个无向图 G = ( N + , E ) G = (\mathbb{N}^+, E)G = ( N + , E ) ,其中 E = { ( u , v ) ∈ ( N + ) 2 ∣ ∣ u − v ∣ ∈ B } E = \{(u, v) \in (\mathbb{N}^+)^2 \mid |u - v| \in B\}E = { ( u , v ) ∈ ( N + ) 2 ∣ ∣ u − v ∣ ∈ B } ,B BB 为给定集合 B ′ B'B ′ 的子集。求一个 B BB 使得 G GG 是二分图,且 ∣ B ∣ |B|∣ B ∣ 尽量大。1 ≤ ∣ B ′ ∣ ≤ 2 × 1 0 5 1 \leq |B'| \leq 2 \times 10^51 ≤ ∣ B ′ ∣ ≤ 2 × 1 0 5 ,B ′ ⊂ N + B' \subset \mathbb{N}^+B ′ ⊂ N + ,max ∣ B ′ ∣ ≤ 1 0 18 \max |B'| \leq 10^{18}max ∣ B ′ ∣ ≤ 1 0 1 8 。
根据二分图的定义,判断 G GG 是否是二分图,等价于判断是否
∀ { a i } ∈ { ( N 0 ) ∣ B ∣ ∣ ( ∑ i a i 2 ) = 1 } : ∑ i a i b i ≠ 0 \forall \{a_i\} \in \left\{(\mathbb{N}^0)^{|B|} \left| \left(\sum_i a_i \bmod 2\right) = 1\right.\right\}: \sum_{i} a_i b_i \neq 0
∀ { a i } ∈ { ( N 0 ) ∣ B ∣ ∣ ∣ ∣ ∣ ∣ ∣ ( i ∑ a i m o d 2 ) = 1 } : i ∑ a i b i = 0
手玩几个样例,我们能够发现 G GG 不是 二分图的一个充分条件是 ∃ b i , b j ∈ B : 2 ∣ ( b i / g ) \exist b_i, b_j \in B: 2 \mid (b_i / g)∃ b i , b j ∈ B : 2 ∣ ( b i / g ) (其中 g = g c d ( b i , b j ) g = gcd(b_i, b_j)g = g c d ( b i , b j ) )。证明如下:显然有 2 ∤ ( b j / g ) ) 2 \nmid (b_j / g))2 ∤ ( b j / g ) ) 。令 a i = − b j / g a_i = -b_j / ga i = − b j / g ,a j = b i / g a_j = b_i / ga j = b i / g ,则 ( a i + a j ) ∤ 2 (a_i + a_j) \nmid 2( a i + a j ) ∤ 2 ,但是 a i b i + a j b j = ( − b j / g ) ⋅ b i + ( b i / g ) ⋅ b j = 0 a_i b_i + a_j b_j = (-b_j / g) \cdot b_i + (b_i / g) \cdot b_j = 0a i b i + a j b j = ( − b j / g ) ⋅ b i + ( b i / g ) ⋅ b j = 0 。然后我们会发现它同时也是必要条件:如果 ∀ b i , b j ∈ B : 2 ∤ ( b i / g c d ( b i , b j ) ) \forall b_i, b_j \in B: 2 \nmid (b_i / gcd(b_i, b_j))∀ b i , b j ∈ B : 2 ∤ ( b i / g c d ( b i , b j ) ) ,则存在 2 t ∣ g c d ( b 1 , b 2 , ⋯ b n ) 2^t \mid gcd(b_1, b_2, \cdots b_n)2 t ∣ g c d ( b 1 , b 2 , ⋯ b n ) 使得 b i / 2 t b_i / 2^tb i / 2 t 为奇数。此时
0 = ( ∑ i a i b i ) / 2 t = ∑ i a i ⋅ ( b i / 2 t ) ≡ ∑ i a i ( m o d 2 ) 0 = \left(\sum_i a_i b_i\right) / 2^t = \sum_i a_i \cdot (b_i / 2^t) \equiv \sum_i a_i \pmod 2
0 = ( i ∑ a i b i ) / 2 t = i ∑ a i ⋅ ( b i / 2 t ) ≡ i ∑ a i ( m o d 2 )
即环都是偶环,所以一定是二分图。
这样我们把 B ′ B'B ′ 中的所有元素按它和 2 114514 2^{114514}2 1 1 4 5 1 4 的最大公约数分类,然后根据上面得到的判据会发现同一类可以任意取,不同类不能取,所以取元素最多的一类就行了。
五维空间中有 n nn 个点 p 1 , p 2 , ⋯ , p n p_1, p_2, \cdots, p_np 1 , p 2 , ⋯ , p n 。如果 ∃ i , j : ∠ p i p x p j > π \exist i, j: \angle p_i p_x p_j > \pi∃ i , j : ∠ p i p x p j > π ,就认为 p x p_xp x 是一个不好的点。求有多少好的点。1 ≤ n ≤ 1000 1 \leq n \leq 10001 ≤ n ≤ 1 0 0 0 。
首先我们对于所有 i , j i, ji , j 预处理 q i j = O p i ⃗ ⋅ O p j ⃗ q_{ij} = \vec{Op_i} \cdot \vec{Op_j}q i j = O p i ⋅ O p j ,然后判定 ∠ p i p x p j > π \angle p_i p_x p_j > \pi∠ p i p x p j > π 就是判定 p x p i ⃗ ⋅ p x p j ⃗ = ( O p i ⃗ − O p x ⃗ ) ⋅ ( O p j ⃗ − O p x ⃗ ) = q i j − q i x − q j x + q x x \vec{p_x p_i} \cdot \vec{p_x p_j} = (\vec{Op_i} - \vec{Op_x}) \cdot (\vec{Op_j} - \vec{Op_x}) = q_{ij} - q_{ix} - q_{jx} + q_{xx}p x p i ⋅ p x p j = ( O p i − O p x ) ⋅ ( O p j − O p x ) = q i j − q i x − q j x + q x x 。直接暴力做是 O ( n 3 ) \mathcal{O}(n^3)O ( n 3 ) 的,能够通过本题 (只要注意一下循环次序使得访存模式较为连续)。如果加一个发现一组 i , j i, ji , j 能判定出 p x p_xp x 是坏点就直接跳出循环可以跑得很快 (据 bzy 说这样可以引入一个不超过 1 / 27 1 / 271 / 2 7 的常数)。
有 n nn 个杯子,第 i ii 个最多能放 a i a_ia i 毫升水,当前已经放了 b i b_ib i 毫升。可以从一个杯子 i ii 倒 x xx 单位水到另一个杯子 j jj (x ≤ a i x \leq a_ix ≤ a i ),但是有一半的水会洒掉,即倒完后 b i b_ib i 变为 b i − x b_i - xb i − x ,b j b_jb j 变为 min ( a j , b j + x / 2 ) \min(a_j, b_j + x / 2)min ( a j , b j + x / 2 ) (杯子 j jj 放不下的水会溢出)。你可以进行任意次 (包括 0 00 次) 倒水操作,之后选 i ii 个杯子,使得选出的杯子中总水量最多。要求对于 i = 1 , 2 , ⋯ , n i = 1, 2, \cdots, ni = 1 , 2 , ⋯ , n 分别解决上述问题。1 ≤ n ≤ 100 1 \leq n \leq 1001 ≤ n ≤ 1 0 0 ,0 ≤ b i ≤ a i ≤ 100 0 \leq b_i \leq a_i \leq 1000 ≤ b i ≤ a i ≤ 1 0 0 ,a i > 0 a_i > 0a i > 0 。
首先容易看出每个水分子最多倒一次,所以最后肯定是选出 i ii 个杯子,然后把剩下杯子的水一个一个一个往这 i ii 个杯子里面倒,倒满为止。其次能够看出一定不会溢出 (假设溢出的话,把溢出来的水保留在原来的杯子里,一定不会让结果更差)。
类似背包,用 f ( i , j , k ) f(i, j, k)f ( i , j , k ) 表示前 i ii 个杯子,选出其中 j jj 个杯子,选出的杯子总容量为 k kk 时最少要洒多少水。则
f ( i , j , k ) = min { f ( i − 1 , j , k ) + 0.5 b i , f ( i − 1 , j − 1 , k − a i ) } f(i, j, k) = \min \{ f(i - 1, j, k) + 0.5 b_i, f(i - 1, j - 1, k - a_i) \}
f ( i , j , k ) = min { f ( i − 1 , j , k ) + 0 . 5 b i , f ( i − 1 , j − 1 , k − a i ) }
第 i ii 个答案就是
j min ( j , ( ∑ b i ) − f ( n , i , j ) ) \max_j \min\left(j, \left(\sum b_i\right) - f(n, i, j)\right)
j max min ( j , ( ∑ b i ) − f ( n , i , j ) )
这样做时间复杂度和空间复杂度都是 O ( n 2 ∑ a i ) \mathcal{O(n^2 \sum a_i)}O ( n 2 ∑ a i ) 。由于需要用 double
类型 (8 88 字节),内存会不够用,需要滚动数组优化空间复杂度为 O ( n ∑ a i ) \mathcal{O}(n \sum a_i)O ( n ∑ a i ) 。
给定一个有根树,它包含 n nn 个节点,其中有 k kk 个叶子节点。你可以给每个叶子节点指定一个不超过 k kk 的正整数权值,要求叶子节点的权值两两不同。对于每个非叶子节点,题目给定其颜色为红色或黑色,红点的权值为它所有儿子权值的最大值,黑点的权值为它所有儿子权值的最小值。求可能得到的根节点 (编号为 1 11 ) 的最大权值。2 ≤ n ≤ 3 × 1 0 5 2 \leq n \leq 3 \times 10^52 ≤ n ≤ 3 × 1 0 5 。
有 n nn 个人,初始时你可以指定血量 { a i } ∈ { 1 , 2 , ⋯ , x } n \{a_i\} \in \{1, 2, \cdots, x\}^n{ a i } ∈ { 1 , 2 , ⋯ , x } n 。每一轮所有还活着的人对其他所有人分别造成 1 11 点伤害,所有伤害在回合结束时同时结算,结算后血量小于 1 11 的人会死掉。如果结算后有且仅有一个活人,就认为这个人获胜。求使得没有人获胜的 { a i } \{a_i\}{ a i } 的个数。2 ≤ n ≤ 500 2 \leq n \leq 5002 ≤ n ≤ 5 0 0 ,1 ≤ x ≤ 500 1\leq x \leq 5001 ≤ x ≤ 5 0 0 。
定义 f ( i , j ) f(i, j)f ( i , j ) 为当前剩余 j jj 个人,且他们的最大血量恰好为 i ii 的情况数,则 i ≥ j i \geq ji ≥ j 时
f ( i , j ) = ∑ t = 2 j ( j t ) ( j − 1 ) j − t f ( i − ( j − 1 ) , t ) f(i, j) = \sum_{t=2}^j \binom{j}{t}(j - 1)^{j - t}f(i - (j - 1), t)
f ( i , j ) = t = 2 ∑ j ( t j ) ( j − 1 ) j − t f ( i − ( j − 1 ) , t )
其中 t tt 表示下一轮还活着的人数。( j t ) \binom{j}{t}( t j ) 表示从当前活着的 j jj 个人选出下一轮还活着的 t tt 个人的方案数。( j − 1 ) j − t (j - 1)^{j - t}( j − 1 ) j − t 表示本轮被打死的 j − t j - tj − t 个人可能的血量 (每个人血量都可能是 1 , 2 , ⋯ , j − 1 1, 2, \cdots, j - 11 , 2 , ⋯ , j − 1 中的任意整数,所以每个人有 j − 1 j - 1j − 1 种情况,然后 j − t j - tj − t 个人乘起来)。i − ( j − 1 ) i - (j - 1)i − ( j − 1 ) 表示下一轮开始时每个人都掉了 j − 1 j - 1j − 1 点血,所以最大血量也会减小 j − 1 j - 1j − 1 。
而 1 < i < j 1 < i < j1 < i < j 时,所有人都会一轮死掉,所以不存在恰好一个人活着的情况,即所有方案都合法,因此只要求出 j jj 个人,最大血量恰好是 i ii 的方案数:
f ( i , j ) = i j − ( i − 1 ) j f(i, j) = i^j - (i - 1)^j
f ( i , j ) = i j − ( i − 1 ) j
答案就是
∑ i = 1 x f ( i , n ) \sum_{i=1}^x f(i, n)
i = 1 ∑ x f ( i , n )
这样就可以 O ( n 2 x ) \mathcal{O}(n^2 x)O ( n 2 x ) 地解决本题。