Codeforces Round #715 A~E

codeforces #715 A~E
by CarolusRex

A. Average Height

点点点

B. TMT Document

点点点

C. The Sports Festival

题意:
给定 n ( 1 ⩽ n ⩽ 2 ⋅ 1 0 3 ) n\left(1\leqslant n\leqslant 2\cdot 10^3\right) n(1n2103)个数,对其重排列。定义 d i = m a x ( a 1 , a 2 , . . . , a i ) − m i n ( a 1 , a 2 , . . . , a i ) d_i = max(a_1, a_2, ..., a_i) - min(a_1, a_2, ..., a_i) di=max(a1,a2,...,ai)min(a1,a2,...,ai),求最小的 ∑ i = 1 n d i \sum_{i=1}^{n} d_i i=1ndi
题解:
在排列 a 1 , a 2 , . . . , a i a_1, a_2, ..., a_i a1,a2,...,ai中,记最大值为 a k a_k ak,如果 k ≠ i k \neq i k=i,那么 d j = m a x ( a 1 , a 2 , . . . , a j ) − m i n ( a 1 , a 2 , . . . , a j ) = a k − m i n ( a 1 , a 2 , . . . , a j ) d_j = max(a_1, a_2, ..., a_j) - min(a_1, a_2, ..., a_j) = a_k - min(a_1, a_2, ..., a_j) dj=max(a1,a2,...,aj)min(a1,a2,...,aj)=akmin(a1,a2,...,aj),其中 k ⩽ j ⩽ i k \leqslant j \leqslant i kji,那么我们对 a k , a k + 1 , . . . , a i a_k, a_{k + 1}, ..., a_i ak,ak+1,...,ai按从小到大排序,一定能获得 d j d_j dj的更优解。最小值也是同样的情况,那么我们可以知道在已有排序 a l , a l + 1 , . . . , a r a_l, a_{l + 1}, ..., a_r al,al+1,...,ar的情况下,两侧新加的值要么是未出现的最小最大值,要么是未出现的最大最小值,进一步的, a l , a l + 1 , . . . , a r a_l, a_{l + 1}, ..., a_r al,al+1,...,ar在大小上应该覆盖了一个连续区间。这时候我们先考虑对 a i a_i ai快排,使得有序。然后这就变成了一个经典的dp问题, d p [ i ] [ j ] dp[i][j] dp[i][j]表示 [ i , i + j − 1 ] [i, i + j - 1] [i,i+j1]的最小 ∑ k = i i + j − 1 d k \sum_{k=i}^{i + j - 1} d_k k=ii+j1dk,由 d p [ i ] [ j − 1 ] , d p [ i + 1 ] [ j − 1 ] dp[i][j - 1], dp[i + 1][j - 1] dp[i][j1],dp[i+1][j1]转移得到。时间复杂度为 O ( n 2 ) O(n^2) O(n2)

D. Binary Literature

题意:
T ( 1 ⩽ T ⩽ 1 0 4 ) T\left(1\leqslant T\leqslant 10^4\right) T(1T104)组数据。
每组数据给定 n ( 1 ⩽ n ⩽ 1 0 5 ) n\left(1\leqslant n\leqslant 10^5\right) n(1n105)和三个长度为 2 n 2n 2n的字符串 s 1 , s 2 , s 3 s_1, s_2, s_3 s1,s2,s3。字符串由 0 , 1 0, 1 0,1构成。求一个长度为 3 n 3n 3n的字符串 S S S使得,S中存在和 s 1 , s 2 , s 3 s_1, s_2, s_3 s1,s2,s3中至少两个字符串相同的两个子序列。 ∑ n ⩽ 1 0 5 \sum{n} \leqslant 10^5 n105

题解:
构造法。
法一:对字符串 s i s_i si,因为仅有 0 , 1 0,1 0,1,那么存在一个出现次数 ⩾ n \geqslant n n的字符,而有三个字符串,则必然有一个字符在两个字符串中出现次数 ⩾ n \geqslant n n,记字符为 c h ch ch,字符串为 s 0 , s 1 s_0, s_1 s0,s1。那么以 c h ch ch为公共字符,增加另一个字符。总的长度必然 ⩽ 3 n \leqslant 3n 3n,这是显然的。

法二:记字符串 s i s_i si的下标为 l i l_i li,那么 s i [ l i ] s_i[l_i] si[li]中必然有两个相同的字符,输出并且对应的 l i + 1 l_i+1 li+1。直到有一个字符串已被遍历完,记此时输出了 k k k个字符,那么总共有 2 k 2k 2k + 1 +1 +1,并且有一个 l i = 2 n l_i = 2n li=2n,那么,其他两个 l i l_i li相加为 2 k − 2 n 2k - 2n 2k2n,则必有一个 l i ⩾ k − n l_i \geqslant k - n likn,输出该 s i s_i si的剩余字符,有 2 n − ( k − n ) = 3 n − k 2n - (k - n) = 3n - k 2n(kn)=3nk个,构造完成。

E. Almost Sorted

题意:
T ( 1 ⩽ T ⩽ 1 0 3 ) T\left(1\leqslant T\leqslant 10^3\right) T(1T103)组数据。
每组数据给定 n , k ( 1 ⩽ n ⩽ 1 0 5 , 1 ⩽ k ⩽ 1 0 18 ) n, k\left(1\leqslant n\leqslant 10^5, 1\leqslant k\leqslant 10^{18}\right) n,k(1n105,1k1018),n表示 [ 1 , n ] [1,n] [1,n]的数组。对其排列,需要满足 a i + 1 ⩾ a i − 1 a_{i + 1} \geqslant a_i - 1 ai+1ai1,输出第 k k k个这样的排列。排列之间的比较是字典序。

题解:
对一个特定满足条件的排列,可以分成多个依次单调减一的区间 [ l k , r k ] [l_k, r_k] [lk,rk]。又因为 l k + 1 ⩾ r k − 1 l_{k + 1} \geqslant r_k - 1 lk+1rk1,如果等号成立,则两区间合并,否则考虑到不重复性,有 l k + 1 > l k l_{k + 1} > l_k lk+1>lk。进一步可以推导出 l k l_k lk是单调递增的,并且 l k l_k lk的排列和整个排列是一一对应的关系。
记T(n)表示长度为 n n n的所有排列数,那么 T ( n ) = ∑ i = 1 n T ( n − i ) T(n) = \sum_{i = 1}^{n} T(n - i) T(n)=i=1nT(ni),表示剩下长度分别为 n − i n - i ni的情况,特别的, T ( 0 ) = 1 T(0) = 1 T(0)=1
S ( n ) = ∑ i = 0 n T ( i ) S(n) = \sum_{i = 0}^{n}T(i) S(n)=i=0nT(i),则 S ( n ) = ∑ i = 0 n − 1 T ( i ) + T ( n ) = 2 ∑ i = 0 n − 1 T ( i ) = 2 S ( n − 1 ) = 2 n S(n) = \sum_{i = 0}^{n - 1} T(i) + T(n) = 2 \sum_{i = 0}^{n - 1} T(i) = 2S(n - 1) = 2^n S(n)=i=0n1T(i)+T(n)=2i=0n1T(i)=2S(n1)=2n,则 T ( n ) = S ( n ) − S ( n − 1 ) = 2 n − 1 T(n) = S(n) - S(n - 1) = 2^{n - 1} T(n)=S(n)S(n1)=2n1。找到这个规律后,我们就可以用二分快速找到需要的数。对于当前状况 ( n , k ) (n, k) (n,k),表示有 n n n个数需要排列,找到第 k k k个排列,只需要找到最大的 K K K,使得 ∑ i = 1 K − 1 T ( n − i ) < k \sum_{i = 1}^{K - 1} T(n - i) < k i=1K1T(ni)<k成立,并更新 ( n , k ) (n, k) (n,k)。那么时间复杂度为 O ( n l o g k ) O(nlogk) O(nlogk)

注意到 ∑ i = 1 K − 1 T ( n − i ) = 2 n − 1 − 2 n − K \sum_{i = 1}^{K - 1} T(n - i) = 2^{n - 1} - 2^{n - K} i=1K1T(ni)=2n12nK。进一步优化的方法是将 k k k转化为二进制,为1表示 a i + 1 = a i − 1 a_{i + 1} = a_i - 1 ai+1=ai1。需要注意的是,在这种情况下,需要将 k − 1 k - 1 k1,这是因为映射关系。另一点是转化后二进制对应的坐标是 [ 0 , n − 2 ] [0, n - 2] [0,n2],而不是 [ 1 , n − 1 ] [1, n - 1] [1,n1]。时间复杂度为 O ( l o g k ) O(logk) O(logk)
这个转化的思路可以从两个角度得到。

  1. 直接考虑 2 n − 1 − 2 n − K 2^{n - 1} - 2^{n - K} 2n12nK,每次找到的 K K K对应了转化成二进制后的第一个1。
  2. 从之前的映射关系入手,即每个 l k l_k lk排列和整体排列的一一对应关系,那么对 a i + 1 = a i − 1 a_{i + 1} = a_i - 1 ai+1=ai1赋1,其他赋0。并且这个二进制对应的排列是符合字典序的。

code

https://github.com/cfuser/codeforces

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值