CF #717 题解

这篇博客详细解析了多项算法竞赛题目,包括贪心策略、前缀异或和、背包问题、区间操作和排列组合优化。通过深入探讨每个问题的解决方法,展示了如何在O(n^2V)到O(k^3)的时间复杂度内找到最优解,并介绍了如何利用错排进行容斥以计算特定条件下排列的数量。
摘要由CSDN通过智能技术生成

CF #717 题解

A - Tit or Tat

贪心地从前面拿数,加到最后一位即可。

B - AGAGA XOOORRR

转化一下,是求是否能把序列分成若干段( ≥ 2 \ge 2 2),每段的异或和都相等。

假设序列的前缀异或和为 S n S_n Sn,共分了 k k k 段,第 i i i 段的最后一个元素是 a i ( a k = n ) a_i(a_k=n) ai(ak=n)

于是有

S a 1 = S a 1 ⊕ S a 2 = S a 2 ⊕ S a 3 = ⋯ = S k − 1 ⊕ S k S_{a_1}=S_{a_1}\oplus S_{a_2}=S_{a_2}\oplus S_{a_3}=\dots = S_{k-1}\oplus S_k Sa1=Sa1Sa2=Sa2Sa3==Sk1Sk

然后就发现:

S a 1 = S a 3 = S a 5 = … S_{a_1}=S_{a_3}=S_{a_5}=\dots Sa1=Sa3=Sa5=

S a 2 = S a 4 = S a 6 = ⋯ = 0 S_{a_2}=S_{a_4}=S_{a_6}=\dots=0 Sa2=Sa4=Sa6==0

考虑一下 n = a k ( k ≥ 2 ) n=a_k(k\ge 2) n=ak(k2) 是多少:

  • k k k 是偶数,则需要 S n = 0 S_n=0 Sn=0,这足以满足条件。
  • k k k 是奇数,则需要 ∃ a 1 ∈ [ 1 , n − 1 ] , S n = S a 1 \exist a_1 \in[1, n-1],S_n=S_{a_1} a1[1,n1],Sn=Sa1 ∃ t ∈ [ a 1 + 1 , n − 1 ] , S t = 0 \exist t\in [a_1+1,n-1],S_t=0 t[a1+1,n1],St=0

如上,可以 O ( n ) O(n) O(n) 判断。

C - Baby Ehab Partitions Again

先转化一下问题,要给每个 i ∈ [ 1 , n ] i\in [1,n] i[1,n] 钦定一个 x i ∈ { − 1 , 1 } x_i\in \{-1, 1\} xi{1,1},使 ∑ i a i x i = 0 \sum_i a_ix_i=0 iaixi=0

稍微再转化一下,两边加上 S = ∑ i a i S=\sum_i a_i S=iai,得到这样一个问题:

n n n 个数可以选或不选(假设选了的数是 a 1 ′ , a 2 ′ , ⋯ a k ′ a'_1,a'_2,\cdots a'_k a1,a2,ak),是否可能

S = 2 ∑ i = 1 k a i ′ S = 2\sum_{i=1}^k a'_i S=2i=1kai

显然容易 O ( n 2 V ) O(n^2V) O(n2V) 用背包判断一开始能否完成条件(并且要注意到这里 S S S 一定要是偶数),若不能完成,答案就是 0。

问题来了,如果可以构成,如何删去最小的数使其不能构成?

  • 如果 a i a_i ai 中有奇数,直接把它去掉, S S S 就变成奇数了,达成条件;
  • 否则,所有数都是偶数,把它们全部除以 2 和原问题有相同的解。一直除到有数成为奇数,转化为上一种情况即可。

D - Cut

显然,若干个数乘积等于它们的最小公倍数等价于这些数两两互质。对每个数先求出在它之后的第一个与它不互质的数,由于 1 0 5 10^5 105 之内每个数至多有五个质因子,可以暴力质因子枚举。不妨把这个数叫做 n x t i nxt_i nxti。那么,如果选择某个数作为左端点,区间右端点最多延伸到哪里呢?我们形象地把这个操作叫做“跳”,即从一个左端点贪心地延伸最大区间,直到不能延伸,到下一个区间的左端点,记这个左端点为 f i f_i fi。则有 f i = min ⁡ j = i n n x t j f_i=\min_{j=i}^nnxt_j fi=minj=innxtj。发现 f f f 数组可以倍增,所以可以 O ( log ⁡ n ) O(\log n) O(logn) 完成一次询问。若将枚举质因子视为 O ( 1 ) O(1) O(1),则本题复杂度为 O ( V + n + q log ⁡ n ) O(V + n + q\log n) O(V+n+qlogn)

E - Baby Ehab Plays with Permutations

我们先算出一个长度为 n n n 的、恰好最少需要 k k k 次交换的排列数量。这可以用一个简单的 d p dp dp:设 f ( n , k ) f(n, k) f(n,k) 为该答案,则有 f ( n , k ) = f ( n − 1 , k ) + ( n − 1 ) f ( n − 1 , k − 1 ) f(n,k) = f(n-1,k) + (n-1) f(n-1, k-1) f(n,k)=f(n1,k)+(n1)f(n1,k1)。这可以考虑最后一个元素是否需要与前面交换,若要交换会交换到哪里(注意到被交换到了的那个元素已经有序)。那么,对于 k k k 的询问,答案就是 ∑ i = 0 k / 2 f ( n , k − 2 i ) \sum_{i=0}^{k/2}f(n,k-2i) i=0k/2f(n,k2i)。这样做的时间是 O ( n k ) O(nk) O(nk)

考虑到 k k k 次交换至多会导致 2 k 2k 2k 个位置发生变化,能不能先挑出 i ( 0 ≤ 2 k ) i(0\le 2k) i(02k) 个位置,然后单独把它们组成的序列进行交换(其它 n − i n-i ni 个位置保持不变)呢?直觉告诉我们一定会算重,不过我们发现可以使用错排进行容斥。我们设 n n n 个元素用 k k k 次交换,且交换后各个元素都不在原来位置的方案数为 g ( n , k ) g(n,k) g(n,k)。则最后答案为 a n s ( k ) = ∑ i = 0 2 k ( n i ) g ( i , k ) ans(k)=\sum_{i=0}^{2k}\binom{n}{i}g(i,k) ans(k)=i=02k(in)g(i,k)

我们考虑怎么计算 g ( n , k ) g(n,k) g(n,k) 。套路性的设限制 P i P_i Pi 表示第 i i i 个数原地不动, M ( t ) M(t) M(t) 表示钦定有 t t t 个限制得到满足,其它随意, N ( t ) N(t) N(t) 表示恰好有 t t t 个限制得到满足。

则有

M ( t ) = ∑ i = t n ( i t ) N ( i ) M(t)=\sum_{i=t}^n\binom{i}{t}N(i) M(t)=i=tn(ti)N(i)

根据二项式反演,

N ( t ) = ∑ i = t n ( − 1 ) i − t ( i t ) M ( i ) N(t)=\sum_{i=t}^n(-1)^{i-t}\binom{i}{t}M(i) N(t)=i=tn(1)it(ti)M(i)

M ( t ) = ( n t ) f ( n − t , k ) M(t)=\binom{n}{t}f(n-t,k) M(t)=(tn)f(nt,k),则

g ( n , k ) = N ( 0 ) = ∑ i = 0 n ( − 1 ) i ( n i ) f ( n − i , k ) g(n,k)=N(0)=\sum_{i=0}^n(-1)^{i}\binom{n}{i}f(n-i,k) g(n,k)=N(0)=i=0n(1)i(in)f(ni,k)

(当然注意到这里的 f f f 是修改过的 f f f),即由“最小 k k k 次”变为了“用 k k k 次”。

于是可以 O ( k 3 ) O(k^3) O(k3) 计算。

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

日居月诸Rijuyuezhu

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值