• AGC037


    Contest page

    A Tag:贪心

    猜想段的长度只会有$1$和$2$(感性理解,应该可以反证……),然后就可以DP/贪心了
    B Tag:贪心、组合

    考虑如何构造合法方案。从右往左考虑球,因为当前球的位置相比于其他未考虑的球靠右,所以它要尽可能产生负贡献(成为三元组的$a$),否则尽可能产生$0$贡献(成为三元组的$b$)。

    产生负贡献的条件是存在其他两种颜色的球构成的二元组,产生$0$贡献的条件是存在一种其他颜色未组成二元组的球。在产生$0$贡献时当前球可以选择一个未组成二元组的球形成二元组,此时对答案有"未形成二元组数量的球"的贡献;而产生负贡献时则对答案有“二元组数量”的贡献。

    将所有贡献乘起来再乘上$N!$就是答案。
    C Tag:构造

    考虑最后一次操作,因为操作是将数字变为当前数字和相邻数字之和,而数都是正的,所以最后一次操作的结果一定会比相邻两个数要大。

    所以考虑倒着做,每一次选择当前$B$序列中不满足$A_x = B_x$的最大值位置$x$,它一定满足比相邻两个位置的值之和大,否则无解。找到这个位置之后我们认为最后若干次操作在$x$上进行,然后进行若干次逆操作直到$A_x = B_x$或者$B_x < B_{x+1}+B_{x-1}$。这么做下去如果发现存在$A_x > B_x$则无解,否则统计逆操作次数即为答案。
    D Tag:构造、二分图匹配

    题目等价于:设$b_{i,j} = lfloorfrac{a_{i,j} - 1}{M} floor$,需要重排行使得$b$的每一列是一个$0$到$N-1$的排列。

    不难证明将某一列安排为$0$到$N-1$的排列之后删去这一列,剩余的$b_{i,j}$矩阵也有解。所以我们按列去做。不难发现这是一个行和数字的匹配问题,Dinic/匈牙利即可构造出一种方案。

    最后我们按照$b_{i,j}$的顺序排列$a_{i,j}$就可以得到第一次输出的矩阵,然后按照$b_{i,j}$从小到大对列进行排序即可得到第二次输出的矩阵。
    E Tag:贪心

    考虑初始的$S$中字典序最小的字符$x$。我们希望$x$在开头出现得尽可能多。

    设初始的$S+rev(S)$中最长的$x$连续段长度$L$,则最后的串的前缀$x$长度一定可以构造为$min{N , 2^{K-1}L}$,因为我们可以将$S+rev(S)$的$L$个连续的$x$放在$S'$末尾,就可以每一次倍长$x$连续段长度,最后把这个连续段放在$S'$的最前面即可。

    对于$2^{K-1}L geq N$的情况直接输出$N$个$x$,否则枚举所有可能的$S+rev(S)$的子串,可以$O(N)$得到进行上述做法之后得到的串。因为有$O(N)$个这样的子串,所以复杂度是$O(N^2)$的。
    F Tag:构造

    我们称一个串$S$是好的当且仅当存在$k$满足:$S$满足$(k,l)$。我们先考虑判断一个串$S$是否是好的。考虑如下做法:

    1、如果串长为$1$那么一定满足;如果串中只存在一种数字,则串$S$是好的当且仅当$|S| geq L$;
    2、否则考虑其中的最小值$min$,并设$S$中下标在$[l_1,r_1]cup[l_2,r_2] cup ... cup [l_k,r_k](forall i in [2,k] , r_i > l_i + 1)$内的所有位置的值均为$min$。
    3、考虑其中所有的区间$[l_i,r_i]$,如果$r_i - l_i + 1 < L$则$S$不是好的,否则将$[l_i,r_i]$的$min$替换为$lfloor frac{r_i - l_i + 1}{L} floor$个$min + 1$,然后回到操作$1$。

    对于操作3的正确性可以这样理解:对于区间$[l_i,r_i]$,在接下来划分的过程当中,这个区间划分出来的所有子区间长度至少为$L$,否则当做到$(min+1,L)$的时候当前串是不好的。所以这$r_i - l_i + 1$个$min$可以等价为$lfloor frac{r_i - l_i + 1}{L} floor$个$min + 1$。用$set$维护整个序列,不难得到序列中出现过的数的总数是$O(n)$级别的,所以复杂度为$O(nlogn)$。

    然后考虑原问题。不妨拓展整个问题,变为:有两个长度为$|S|$的数组$L_i , R_i$,你需要求出$sumlimits_i sumlimits_j L_iR_j [S_{i,j} is good]$。原问题显然是拓展问题的$L_i = R_i = 1$的情况。对于这个问题,与上面的做法类似:

    1、如果串中只存在一种数字,可以前缀和$O(n)$计算答案;
    2、否则考虑其中的最小值$min$,并设$S$中下标在$[l_1,r_1]cup[l_2,r_2] cup ... cup [l_k,r_k](forall i in [2,k] , r_i > l_i + 1)$内的所有位置的值均为$min$。
    3、考虑其中所有的区间$[l_i,r_i]$,计算左右端点在$[l_i,r_i]$内的答案,并将$[l_i,r_i]$内的所有$min$替换为$lfloor frac{r_i - l_i + 1}{L} floor$个$min + 1$,更新$LR$数组,然后回到操作$1$。

    问题是如何更新$LR$数组。我们举题解中的例子来解释(因为真的不好直接讲啊QAQ):

    考虑序列$1 1 1 1 1 1 1 1 1 a b c d e$,其中$a,b,c,d,e>1$,$L=3,min=1$。那么接下来序列会缩成$2 2 2 a b c d e$。考虑新序列的串$2 2 a b c$,它可以对应原序列中$underbrace{1 1 ... 1}_{6 sim 8 ext{个}1} a b c$,因为这样的串可以通过上述操作变为$2 2 a b c$。这意味着$L'_2 = L_2 + L_3 + L_4$。其余的$LR$是类似的。

    总复杂度和上面一样是$O(nlogn)$的。有一些细节:1、对于3操作中新加入的数字段,需要把左右端点在这个数字段内的贡献减掉避免重复;2、注意$r_i - l_i + 1 < L$的情况,可以认为在序列中插入了一个分隔符,稍微需要一些操作。实际上只要把这一段放在这里不管就可以了,因为在之后的过程中也不会考虑到这些段,所以放在这里就相当于一个分隔符。
  • 相关阅读:
    配置支持Basler的API函数的开发环境
    调用约定
    进程间通讯之 命名管道
    进程间通讯。
    使用结构体返回多个参数。
    目的:让目标程序在内存中只有一个实例
    数学问题
    机试二
    pycharm安装TensorFlow
    机器学习一
  • 原文地址:https://www.cnblogs.com/Itst/p/11372789.html
Copyright © 2020-2023  润新知