AtCoder做题记录

AtCoder做题记录

[ARC082F] Sandglass

题意:有一个沙漏,每秒会有1g沙子从上面落下来,有\(k\)个时刻\(r_1,r_2\cdots r_k\),每到\(r_i\)沙漏就会翻转,多次询问如果一开始上部有\(a_ig\)沙子,在时刻\(t_i\)时上部有多少沙子。

思路:一开始的思路是每个操作形如\(x\rightarrow max(x-\Delta r,0)\),可以按时间轴用线段树维护答案,没想到这题竟然可以做到线性。

其实线性做法的思路也是维护如果一开始是多少此时就有多少,记为\(f_i\),那么可以把\(f_i\)的图像画出来,发现就像这样img最终值不和上下界(红线)相等的\(f_i\)必然满足在一个区间内,因此我们只用这个区间的左右端点维护上下界即可做到线性。

[AGC027D] Modulo Matrix

题意:构造一个\(n\times n\)的矩阵,要求满足:每个元素不超过\(10^15\)且互不相同,对于任意两个相邻的数\((x,y)\)\(\max(x,y)\mod \min(x,y)\)必须相等。

思路:我也不知道这么人类智慧的做法是怎么想出来的。首先,把这个矩阵黑白染色,钦定白格子的数是所有相邻的数的\(\text{lcm}+1\),那么可以很好的满足后两个条件。接着考虑用质数来填上面的数,不过这样做要用\(O(N^2)\)个质数,白格子的数可能超出范围,于是就要想办法用尽量少的质数来完成这件事。考虑这样一种构造,给每条黑格子所在的对角线分配一个质数,这个黑格子的数就是这两个质数的乘积,再简单调整一下顺序,这样就可以保证数字大小不超过\(10^15\)

[AT_code_festival_2017_quala_d] Four Coloring

题意:给一个\(n\times m\)的网格,有4种颜色,要给每个点染色,要求网格上任意一对曼哈顿距离为\(d\)的格子的颜色不同。

思路:这道题要用到一个小trick:曼哈顿距离转切比雪夫距离,其实本质就是把一个斜着的正方形变成了正着的,这样就更方便处理。于是就可以把网格分成\(d\times d\)的一个个小网格,每个网格里染同一种颜色,每\(2\times 2\)的大网格按\(\begin{matrix}R\;\;Y\\G\;\;B\end{matrix}\)(其实可以随意)染色即可。

[ARC082E] ConvexScore

题意:给定平面上\(n\)个点,定义一个点集大小为\(|S|\)的凸包的权值是:记所有在这个凸包内部和边界上的点的个数为\(k\),则价值为\(2^{k-|S|}\),求所有有面积的凸包的权值和。

思路:考虑组合意义。\(2^{n-|S|}\)表示的其实是所有能组成和这个凸包一样的凸包的点集个数,于是答案就是所有能组成凸包的点集个数。答案可以用所有点集个数\(2^n\)减去所有不能构成凸包的点集个数,求法可以直接枚举两个点然后暴力判断有多少个点在线段上,再减去对应贡献。复杂度\(O(n^3)\)

[AGC003E] Sequential operations on Sequence

题意:有一个数组,初始是\(1\)$n$,有$Q$次操作,每次操作会把数组长度变成$a_i$,新增的数是上一次操作后数组的重复,求最终数组中$1$\(n\)每个数出现了多少次。

思路:首先,如果上一次操作的长度比这一次要长,那么上一次操作是没用的,这一步可以用单调栈维护,于是最终会留下一个递增的操作序列。接着我们考虑倒推,第\(i\)次操作后一定是上一次操作后的序列完整重复若干次,再加上一段长为\(a_i\mod a_{i-1}\)的前缀,那么这个前缀怎么处理呢?我们再往前看,如果之前存在\(j\)使得\(a_{j-1}<d\leqslant a_j\),那么这个前缀也一定是\(a_{j-1}\)重复若干次再加上一段长为\(d\mod a_{j-1}\)的前缀,于是可以递归处理,最终\(d=0\)是要对当前段区间加,差分一下即可。复杂度的话,每次取模\(d\)至少减半,这一步是\(O(\log n)\)的,而二分查找也是一只\(log\),于是复杂度是\(O(\log^2)\)的。

[AGC016D] XOR Replace

题意:给定序列\(a\)\(b\),每次可以把\(a\)序列的一个数变成\(a\)序列的异或和,求把\(a\)变成\(b\)的最少的操作次数。

思路:发现第一次把一个数\(a_i\)变成异或和\(S\)后,此时的异或和是\(a_i\),因此每次操作相当于是把一个数变成上次被操作的数。简化一下,就相当于把异或和当做第\(n+1\)个数,每个操作可以把一个数和最后一个数交换。首先可以简单判断是否有解。接着考虑怎样让操作次数最小。发现这很类似排列的置换问题,于是考虑没对不同的\(a_i,b_i\),让\(a_i\)\(b_i\)连边,最终答案即为边数+联通块数-1。证明很简单,因为在同一连通块内可以用边数次完成,而从一个连通块到另一个连通块要花1的代价,一开始就在的连通块不同花这1的代价。复杂度\(O(n\log n)\)

[AGC016E] Poor Turkeys

题意:有\(n\)只鸡和\(m\)个人,每个人一次操作,每个操作会选择两只鸡\(x,y\),如果两只都活着,那么会等概率吃掉一只,如果一只还活着就吃掉这一只,否则什么都不做,求有多少对\((i,j)\)满足在最终时刻第\(i\)只鸡和第\(j\)只鸡可能都还活着。

思路:设集合\(f[i]\)表示如果最终\(i\)活下来了,那么哪些\(j\)不能活着。如果一个人选的是\((i,x)\),那么如果要让\(i\)活下来,\(x\)就必须死,且在之前必须活着。于是考虑倒推,对于当前的\((x,y)\),如果\(x,y\in f[i]\),那么\(i\)最终肯定不能活下来,否则如果\(x\in f[i]\)或者\(y\in f[i]\),那么剩下的一个也得加入进\(f[i]\)中。统计答案时,如果\(f[i]\)\(f[j]\)无交,那么这一对就有可能都活下来。复杂度\(O(nm+\frac{n^3}{w})\)

posted @ 2023-05-26 15:33  Xttttr  阅读(16)  评论(0编辑  收藏  举报