【Codeforces】GoodBye 2019简要题解

传送门
七道构造题,外加一道暴力,妙啊! 话说构造题太考验思维了,想不到就没了。

A.Card Game

  • 直接贪心即可

B.Interesting Subarray

  • 可以发现当且仅当存在相邻的两个不满足条件时才存在,也就是说任意一个不合法的子段一定有这么一个相邻的位置不合法。

C.Make Good

  • 因为要求ai=2(a1xora2xor...ak)sum a_i=2*(a_1 :xor:a_2:xor...a_k),注意到有一个乘二,所以说最后一个位置相当于是已经确定了,然后倒着推过去就可以O(log)的时间用一个数完成要求的构造。
  • 或者还有一种构造方法。设刚开始的和为s1,异或和为s2。
  • 第一个数是s2,第二个为(s1+s2)。然后发现这样就可以了???神奇。

D. Strange Device

  • 简单交互题 构造题。
  • 只需要将前k+1个选择k次,那么返回的只会有第m大的出现k+1-m次,第m+1大的出现k次,然后找到返回值中小的那个的个数就好了。

E. Divide Points

  • 刚开始一本正经地以为是神仙的二分图匹配的问题,结果还是构造???
  • 奇偶讨论。因为要讨论(x1x2)2+(y1y2)2(x_1-x_2)^2+(y_1-y_2)^2的关系,所以直接按照x,y分别的奇偶性讨论即可,一共有四种可能。
  • 注意到如果有不止一种可能,那么就一定能分成两组(如果x-y都同奇偶,有两组,那么它们最后的距离mod4是不一样的)。
  • 否则全部坐标除以二继续做。可以预先全部变成正数。

F. Awesome Substrings

  • 首先计算一个前缀和记录为s[i],那么相当于是求
    k>00<=l<r<=n[k(s[r]s[l])=(rl)]sum_{k>0}sum_{0<=l<r<=n} [:k(s[r]-s[l])=(r-l):]
  • 注意到k如果很大的话那么ks[m]<=nk*s[m]<=n,那么有效的s[m]s[m]满足s[m]<=nks[m]<=frac{n}{k}
  • 那么我们就可以平衡规划了。
  • k<=Tk<=T时暴力O(Tn)O(Tn)k>=Tk>=T的部分枚举左端点ll以及1的个数,计算右端点在这个区间内满足k>=Tk>=T的个数,时间O(n2/T)O(n^2/T)
  • 可以用map完成暴力(虽然超级慢),然后要求上面两个时间相等即可。

G. Subset with Zero Sum

  • 真·构造。首先化一下很丑的约束式子变成1<=ia[i]<=n1<=i-a[i]<=n
  • 超级优美——直接i向a[i]连边,然后找环即可。

H. Number of Components

  • 基础线段树
  • 刚开始想建一个树出来LCT,然后似乎有单调队列???难搞
  • 然后发现一个性质,联通快一定是连续的一段区间。否则左边一块隔着几个和右边一块相连,你会发现中间的几个一定会和左边的或右边的相连。
  • 既然如此,那么问题就转化为了找分界点了。
  • 分界点xx一定满足Mini<x(ai)>Maxi>=x(ai)Min_{i<x}(a_i)>Max_{i>=x}(a_i)
  • 现在我们想要维护分界点的个数。直接做并不好做。考虑转换一下模型。
  • 对于上面的式子我们不妨找到Mini<x(ai)Min_{i<x}(a_i)ii,将aj>=aia_j>=a_ijj的位置赋为1,aj<aia_j<a_i赋为0.那么最后对于这个ii,我们得到的序列是类似11…110…00这样的。如果我们在这个序列前面加一个1,后面加一个0,那么这个序列hh是这个形态当且仅当相邻位置不同的个数为1.
  • 我们对于每一个ii都维护一个hh的相邻位置不同的个数ff,以a[i]a[i]为关键字开一个权值线段树,维护ff
  • 可以注意到修改一个位置pos只会跟pos-1或pos+1在h中与pos的0/1状态有关,影响到的刚好是一个区间。分类讨论即可。
  • 线段树上只需要记录最小的是什么和最小的数的个数。
  • 由于修改自己不好改,所以不妨离线下来,全部一起操作。预处理也可以变成类似的操作。
原文地址:https://www.cnblogs.com/DeepThinking/p/13090894.html