7月杂题选做

上回说到:2022.6

关于难度

可以秒杀的题。

思考一会儿后可以秒的题。

需要较长时间思考的题。

看题解、稍加指点就会做的题。

看题解后需要较长时间消化,甚至现在都没有完全理解的题。


打了 ABC258 阴间场,EF 都是超级阿拉丁题,G和 Ex 是思博题。

开局写 E,直接WA 一发,然后秒了 G,回去 E 把 E 过了,然后冲 F 调了很久过了,此时已经过了一个小时了。

发现 Ex 是直接来,100 分钟的时候过了。

接下来写 ABCD,D写完最后一秒交了,结果 WA 了,后来调一下才发现 Inf 开了 1018 WA,开 9×1018 过了。。我只能流汗。


ABC258Ex *2708

求有多少个序列 a,满足每个元素都是奇数,和为 S,且不存在一个前缀和 A

|A|105,Ai1018

考虑每次要么是把结尾数+1,要么是新开一个 1,照这个思路做,设 fi,0/1 表示当前和为 i,最后一个数是否是奇数,那么转移显然可以矩阵快速幂。

要扣掉的点相当于后面次操作必然把结尾数+1。

code


CF1687C *2500

有两个序列 a,b,有 m 个区间,每次操作选择一个区间,需要满足这个区间 a 的和等于 b 的和,然后可以任意修改这个区间中的数,但需要保证操作后和依然相等,问是否可以操作若干次使得 a=b

n2×105

显然前缀和一下,然后相当于两个相等的且连边的点就可以把中间的全部联通。

考虑维护这个东西,我是直接写了一个 set,然后跑搜索,当然也可以用并查集维护。

code


打了 CF1700,非常罕见,id

秒了 D,回头过了 C,此时 psz 居然还没有过 AB??然后去 E,发现一眼秒了,但是去吃饭了,回来的时候 psz 已经过了E。最后 rk 4。


CF1700E *2600

题目比较长,自己看吧。

很直接来的题,0 很好判,相当于只需要考虑交换一次是否可行即可。

考虑一个位置如果不合法,那么就是这个位置小于旁边四个数并且不是 1

考虑修改这旁边的 5 个数字可能会产生影响。

那么开桶记录每个位置最多会给多少个不合法的点产生影响。

然后直接暴力扫,判断是 O(1) 的。

code


CF1700F *2600

有一个大小威 2×n01 矩阵,给一个初始状态和目标状态,可义把 1 进行匹配,匹配代价是两点曼哈顿距离,求最小代价。

n2×105

想了半天 dp,结果是直接贪。

从左往右,然后记录上面和下面剩多少个 1,上下不平衡就调整,然后一直向后移动就好了。

code


CF932F *2700

有一棵树,每个节点有权值 a,b,从一个节点 x 每次可以调到一个子树中节点 y(xy),获得价值是 ax×by,一直跳到叶子,总价值是所有价值之和,对于每个点求出最大总价值。

n,ai,bi105

不错的题。

考虑设 fi 表示 i 点的答案,那么可以得到转移方程:

fx=maxysonxfy+ax×by

这种式子看着就很能斜率维护,由于是子树中维护,所以考虑 dsu on tree 一下,然后用李超树动态维护即可。

code


CF1699E *2600

已知 n 个数,值域是 [1,m],每次操作选择一个数 x,拆成两个数 p,q 满足 pq=x,p,q1,求若干次操作以后的最小极差。

n106,m5×106

不错的题。

考虑从大到小枚举最小值,问题相当于对每个数 ai 拆成若干个 x 的数然后需要满足最大值最小。

相当于每次加一个数然后去更新。

那么咋去更新呢,每次加入一个 y,记录 mxi 表示 i 拆成的最大值,那么对于所有 y2i,都可以把 i 拆成 y,iy 来更新。

code


打了 ABC259,unr 乱打。

开局看 E,发现思博,先去 F,F 就是直接树形 dp,还是调了一点时间,15 分钟过了,然后看 G,毛想想网络流就先跳了,看 Ex,马上有一个 O(n4) 的暴力,又想到了 AGC001E 的那个 trick,两个拼一下就过了,37 分钟,然后 G 建图一眼,直接来,50 分钟,最后写了一下 E,56 分钟然后直接润了。

可惜的是 psz 没有AK,差一个 G,psz先 AK ABC 还是国足先进世界杯?


ABC259G *2428

有一个 n×m 的矩阵,每个格子有一个数,现在选择若干行染成红色,再选若干列染成蓝色,如果一个点满足权值是负数且被染上两种颜色就不合法,最后得分为所有有颜色的格子数之和,求最大得分。

n,m100

不是很难的题,显然选一行一列的贡献相当于行之和加列之和减去中间那个。

容易想到建图,每行建一个点,每列建一个点,然后先把所有贡献加起来然后减去最小割就好了。

建图就是直接行向列连边,连的是中间那个数。

code


ABC259Ex *2406

有一个 n×n 的矩阵,每次可以向下或者向右走,问有多少条路径满足起点和终点上的数字相同。

n400

最简单 Ex。

考虑先把同数字的位置放一起,然后做。

有一个很简单的暴力,就是枚举起点终点然后组合数,这个在相同数字很多的时候会寄。

此时可以想到 AGC001E 一个数字可以用 O(n2) dp 做,设 fi,j 表示 (i,j) 左上角的点走到 (i,j) 的总距离,直接转移,然后就没了。

复杂度 O(n3)

code


AGC009E *3428

n1m0 ,每次操作选择 k 个数,把他们删除并加入那么的平均数,最后会剩下一个数,问这个数有多少种可能。

n,m,k2000

不错的题。

显然最后的操作可以看成是一个 k 叉数,一个叶子对答案的贡献就是 1kd

考虑把最后的数写成 k 进制小数的形式。

考虑如果不进位相当于就是数位和为 n,长度为 d=n+m1k1,直接背包即可。

考虑如果有进位,显然就是 n 减去 k1,但是 d 也需要减一,不然无法用 m 凑出 1zz 是最后的数。

code


CF883J *2400

m 个建筑,每个建筑拆除需要 pi代价,装修需要 bi 代价。有 n 个月,每个月预算 ai。每个月可以拆除若干建筑,但为了欺骗市民是装修,需要 bjai才能拆除 j 建筑。拆除可以用到之前存的预算。求最多拆除多少个建筑。

n,m105

考虑资金可以留到下一个月,那么显然把钱放到 ai 比较大的月去花,这个显然可以单调栈维护。

越到后面 ai 越小,因此考虑从后向前做,可以开堆维护当前可以选的房子,那么一个贪心策略是一直找最小值拆掉。

这样会有一个问题,就是会有多余的资金。

其实也很好处理,就是找到最小的减去多余资金再放回去,因为前面的资金可以留到后面用,就相当于拼在一起把这个建筑拆了。

code


CF1697E *2400

平面上有 n 个点,你需要给它们染上 n 中颜色,满足以下两个条件:

  • 同一颜色的点两两距离相等。
  • i 到同颜色点的距离严格小于到不同颜色点的距离。

这里距离是曼哈顿距离,也就是 |xixj|+|yiyj|

求染色方案数对 998244353 取模的结果。

不错的题,就是特殊情况比较多。

首先可以利用条件二,求出每个点到其他点的距离最小值 mni,也就是与 i 同颜色的点离 i 的距离一定是 mni

可以按这个连边,如果 mni=mnj=disi,j 那么就连边。

显然直接考虑每个连通块,一个连通块中的边一定都满足权相等。

此时一个颜色的就相当于是一个完全图。

注意严格小于,也就是一个连通块要么每个点一个颜色,要么全部是一个颜色,不然就寄,也就是判断这个连通块是否是个完全图。

也就是两种情况,那么考虑像个背包一样直接转移,令 fi 表示当前已经选了 i 个颜色的方案数,然后两种情况分别转移很 ez。

但有一个寄吧情况我想了很久,就是如果 mni>mnj,disi,j=mni,此时显然是不连边的,但是 i 所在的连通块就不可能染成一个颜色了,因为不满足条件二。

code


CF1691F *2500

有一棵 n 个点的树,定义 f(r,S) 表示根为 r 时,包含点集 S 的最小子树大小。

已知常数 k,求

rV|S|=kf(r,S)

n2×105

最小子树大小实际上就是 S 中所有点的 LCA,因此考虑每个点作为 LCA 时对答案的贡献。

两种情况,假设当前选择的点是 x,一种是 x=r,那么此时就是有至少两棵子树中有点被选,要么 rx,那么就相当于把 r 所在子树扔掉后,剩下的点中选,并且使得至少两棵子树中有点被选。

两棵子树有点被选这个东西是个,可以直接容斥,所有方案减去只在一棵子树中的方案即可。

方案组合数算算就好了,这题其实可以开桶然后卷积解决多个询问 k


CF1701E *2500

一开始有一个字符串 t,你需要通过若干次操作把它变成 s,开始时光标在最后。

操作有下面几种:

  • 光标左移一格。
  • 光标右移一格。
  • 光标跳到最后。
  • 光标跳到最前面。
  • 删去光标左边的一个字符。

问最少几次操作。

n,m5000

降智了,思博题不会做。

先考虑怎么操作优,有一个简单的操作方式是不一样就删除,否则向左跳,这样操作次数 nm

但是也可以在左边删。

左边删必然就是先跳到最左边,然后一直向右边,遇到一个需要删掉的就删掉。

可以发现,左右最后一定会留下中间一个区间不用动。

这个区间的长度咋求,可以用 dp,fi,j 表示 sitj 位置开始向后最多匹配多少位,这个可以直接 O(n2) dp,然后直接枚举每个连续段就做完了。

code


CF1701F *2500

定义一个序列 a 的价值是 i<j<k 的个数满足 i,j,kakidd 为给定常数。

现在有加数,删数操作,每次操作后输出序列价值。

n,ai2×105

不是很难的题。

考虑每个三元组在左边统计,那么考虑加一个点的贡献。

如果它是 i,那么显然就是查询后面有多少个点直接算就好了。

考虑它不是 i,那么相当于前面 [xd,x1] 范围内的点后面就多了一个点,产生的贡献也就是这些地方原来后面的点的和,这个直接算加入到答案中,然后再对前面进行区间修改即可。

如果对前面有点的地方进行修改这个比较阿拉丁,可以令 s1 表示是否有这个点,s2 表示 [x+1,x+d] 区间中数之和,那么计算贡献时直接 s1×s2 即可,这些都可以线段树简单维护。

代码不是很难写。

code


CF1685D1 *2800

有一个长度为 n 的排列 p ,定义一个排列 q 的价值为

i=1n|qipqi+1|

qn+1=q1

构造一个 q 使得价值最小。

n400

不错的题,反正我不会。

下面是我的寻宝做法,会 WA。

看到排列先想置换环,可以发现如果只有一个置换环比如说 2 3 4 1,可以发现可以轻松构造出 1 4 3 2 使得价值为 0

因此考虑置换环合并,贪心地让一个置换环中的数放在一起,然后可以发现价值就是每个置换环最后一个数的最大值减去最小值的两倍,因此直接双指针即可。

code

结果证明这个做法是在是太寻宝了,WA 2。

正解比较牛逼,开局就是一个不是常人可以想出的构造。

qi=wqi+1

这样可以把原式变成

i=1n|wipi|

而且这个 wp 没有任何关系,因此可以通过 w 来反推 q

考虑怎样的 w 是合法的。

对应到置换环上,相当于有 qi+1qi 也就是形成一个置换环。

此时问题变成,求一个 w 满足是一个置换环而且上面那个式子最小。

然后直接贪心,如果 i,i+1 所在位置不在一个环上那么就把这两个数交换,这样可以在 2 的代价下合并两个环,达到了答案的下界。

code


CF1684G *2800

给两个数做辗转相除法,然后把中途得到的余数全部放在一个序列中,现在有若干对数进行了这样的操作,把最后得到的总序列打乱告诉你,求原来这若干对数,最后总序列长度为 n,构造出的数不能超过 m

n103,m109

不错的题,但感觉不是特别难。

考虑 xmody<x2(x>y),那么可以发现如果最后序列中存在一个 x 满足 2mm 就寄了。

然后对于一个数 x 而言,有一个简单的构造方案是 2x,3x,这样可以去掉一个数,但是要求是 3xm

因此只需要考虑 m2xm2 中的即可。

这些 x 显然需要去前面找一个数 d 来一起做,一个容易的构造是 x+d,2x+d,这样相当于 xd 去做辗转相除。

可以发现 d 一定取 x 的因数最优,因为这样不会删掉其他数。

这个匹配是否可行问题可以直接网络流。

code


CF1684F *2600

有一个长度为 n 的序列,有 m 个区间 [li,ri],可以选择一个区间然后对这个区间进行任意修改,使得对于 m 个区间,都满足这个区间中的数互不相同。

求选定区间最小值。

n2×105

不是很难的题。

考虑如果当前选定了一个区间,那些相同的数会使得这个区间寄掉。

要么前缀,要么后缀,要么就是跨过这个区间。

那么直接对三个维护一下,直接双指针维护一下即可。

code


CF1682F *2700

有两个长度为 n 的序列 a,bQ 次询问一个区间,满足 lirbi=0,可以进行若干次操作,每次使 bi 减一,bj 加一,花费是 |aiaj|,求将所有 b 变成 0 的最小花费。

保证 a不增序列

n,Q2×105

不错的题。

原题意很阿拉丁,转化成这样方便做题。

既然是不增的,那么实际上不需要连那么多边,i 只需要向 i+1i1 连边就行了。

那么直接考虑每条边的贡献,相当于是右边剩余的需要流到左边去。

lir|srsi|(ai+1ai)

s 就是 b 的前缀和。

统计答案很简单,直接排序后加入去掉绝对值,然后树状数组维护即可。

code


CF1681E *2600

题比较长,自己看吧。

简单题,有机会在写吧。

就直接来,fi,j,0/1,0/1 表示 i 向上 2j 层,门状态为 0/1 的最短路,直接倍增就好了,感觉很阿拉丁,不写。


CF1680F *2600

有一个 n 个点 m 条边的图,需要给点黑白染色,需要满足最多只有一条边相连的两个点都是黑点,没有一条边相连两个点都是白点,求方案。

n106

先不考虑最多一条的那个限制,显然就是直接黑白染色,满足条件的图就是二分图。

考虑最多一条的限制,显然删掉这条边就满足是二分图了,因此直接线段树分治即可,时间复杂度 O(nlog2n) 需要一定卡常。

code

好像有线性做法。


CF1680D *2400

有一条狗一开始在数轴 0 点,给定它长度为 n 的行走路线,ai 表示 i 时刻向右走 ai,有些位置是 0 表示这个时刻行走距离未知。

需要把所有 0 替换为 [k,k] 中的一个整数,要求最后走到 0,求狗最多会经过多少个不同的格子。

n3000

直接考虑前缀和一下,那么答案就是 max(maxsiminsi)

考虑枚举 maxmin 出现的位置 i,j,那么会对答案产生影响的只有这个区间中的 0,直接找可以修改的和的最大值和最小值即可。

code


CF1679F *2600

题比较长,自己看吧。

考虑相当于连边求连通块个数。

一个联通块我们在字典序最小的那个地方进行统计,然后就不会了,看了题解。

考虑这样一个问题,如果有一个数 i 满足在一个 j,(j>i) 的后面,而且 i 可以移动到 j 的前面那么就寄。

然后就从后向前进行 dp,设 fi,S 表示当前到了第 i 个数,当前可以移动到 i 前面的数的集合为 S 的方案数。

那么直接来就好了。

code


CF1679E *2400

定义 f(S) 表示字符串 S 中有多少个不同的回文子串。现在已知有一个串 T 有一些地方是 ? 。现在有 Q 次询问,每次询问给出一个字母集合,求所有把 ? 换成集合中字母所得到的所有字符串 Sf(S) 之和。

n1000,Q2×105,字母只有前 17 个。

洛谷翻译什么寄吧。

看到字符集比较小,考虑状压。

枚举每个回文串,考虑它在什么时候会对一个询问产生贡献。

发现回文串匹配有几种情况。

如果左右都是 ? 那么就是在字符集中随便选一个。

如果有一边是 ? 那么询问的字符集要包含这个字母。

考虑这个包含,第一部分贡献只与字符集大小有关,所以设 fi,S 表示字符集大小为 iS 的子集的贡献和,直接高维前缀和即可。

code


CF1673F *2400

题比较长,子集看吧。

这个路径有长度限制,显然不能像样例那样搞。

考虑从 (1,1) 出发,一个简单的操作就是给每个点一个权值表示走到这个地方的异或值,且无论怎么走都一样。

一个简单的构造就是边权就是相邻点权的异或和。

然后随便写了个构造,发现 >150000 寄。

考虑优化,既然要相邻异或小,考虑格雷码,直接行做一次列做一次就好了。

结果是 80000 多一点,寄。

再考虑两个二进制位分开考虑,显然最优操作是 0,1,2,3 依次放在左上,右上,左下,右下。

这样是 60000 多一点。

不会了,看题解。

考虑一个简单构造 pi1i 的 lowbit 的异或和。

这样是一个排列,证明比较简单,而且性质是格雷码的加强版。

直接来,按前面的二进制位和后面的分组,构造会寄。

但如果按二进制位奇偶性分组,就可以过了。

code


CF1556F *2500

题目比较长,自己看吧。

数据范围显然是在提示状压,因此直接来,设 fi,S 表示 i 可以在集合 S 中是 winner 的概率。

直接来比较困难,因为这个东西有传递性,考虑容斥一下,相当于 1 减去不合法的概率。

不合法就是有一个子集满足这个子集中的点到其他点都是赢,集合中剩余的点,i 个当 winner。

也就是

fi,S=1TSfi,T×gT,ST

gT,ST 就是 T 对其他都赢的概率。

code


ARC144D *2468

问有多少个长度为 2n 的序列(下标为 [0,2n1])满足

  • 0aik
  • ai+aj=ai&j+ai|j

n3×105,k1018

首先显然是给每个二进制为附上一个权值,让在给 a0 附上一个权值,那么 ai 就是 i 的二进制为权值之和再加上 f0,然后就不会了。

假设一个二进制为的权值是 pi,那么对于选出一种方案后,考虑 f0 有多少种选法,这个选法显然之和正数之和和负数之和有关,然后可以发现一个 pi 会使答案减少 |pi|

也就是要算

max(0,K+1|pi|)

考虑枚举方案,那么如果一个非 0 的数会有两种方法,因此直接枚举有几个非 0 的数,那么所有的数都变成了正数,只需要考虑所有数的和加上 f0 K 就好了。

i=0n2i(ni)j=0k(ji)=i=0n2i(ni)(k+1i+1)

code


P7215

有一棵 n 个点的树,每个点有一个颜色,每次操作可以把两个颜色合并,求最少几次合并满足存在一种颜色满足这个颜色的所有点构成一个连通块。

n2×105

可以直接点分,最后的连通块要么是经过分治中心,要么在一个子树里,因此只考虑经过分治中心的,直接来就好了。

考虑这样一种做法,对每个颜色建一个点,如果满足有一个颜色 a 的点在两个颜色 b 的点的路径上,那么就 ba 连一条有向边,表示选 b 就必须选 a,那么最后的答案就是缩点后出边为 0 的最小的强联通分量。

考虑这个连边咋做,对于一个颜色 a,先选出所有点的 LCA,然后 a 要连向每个点到这个公共 LCA 路径上的所有颜色。

此时就可以直接树剖维护了,记录每个重链的集合然后优化建图即可。

我写了一个假做法,没想到过了。

就考虑一个点向上面的连,如果一个点 i 满足颜色为 a 并且是颜色为 a 的 LCA,令这个点为 “好点”,因为不能向上面连边了。

那么一个点向上面连边只要找到第一个不是好点的点即可,对好的点也暴力连边即可。

但这样是 O(n2) 的,构造也比较简单,先上面一条链全部是好点,然后下面开一个菊花即可,不知道为什么没有人卡。

code

AT 最短解是 O(n) 的,但是被洛谷老哥卡了。


P3643

n 个数,第 i 个取值为 [li,ri],也可以选择把这个数扔掉,但是不能把所有数都扔掉,求有多少种方案满足最后的序列单调递增。

n500,li,ri109

考虑值域很大,直接离散化一下,那么取值就变成了一段段区间。

考虑设 fi,j 表示 i 在区间 j 的方案数。

那么直接去枚举一个后缀 [k,i] 满足都在 j 这个区间中即可,由于这个状态是保证 i 必须选,因此最后加一个极大值即可。

此时考虑中间的组合数计算问题,就是 s 个数,取值为 [1,n],每个数可选可不选,求递增方案。

这个东西考虑有 n+s 个球,里面选 s 个,那么右边 s 个就表示每个球选不选,左边表示选那些数,这个显然一一对应。

code


P3248

题比较长,自己看吧。

如果不是因为模拟赛,狗都不做这个题。

超级阿拉丁,考虑如果知道最后的树去查询相当于先对一块块树去求个 LCA 使得两个走到同一个里面去,然后再在这个小树里面求 LCA。

但是一个问题是每次修改操作是把子树中排序再挂的,怎么确定一个点对应原树的编号?

相当于在 dfs 序上一个区间第 k 大,主席树维护即可。

code

2.92k,真的阿拉丁。


CF505E *2900

n 个竹子,第 i 个初始搞为 hi 每天会长高 ai,每天可以进行 k 次操作,每次选一个竹子砍掉 p(不足则砍为 0),求最后最高竹子的最小值。

n105,m5×103

牛逼题。

显然的思路是先二分,但是会发现直接做很困难,因为操作次数过多会变成 0 造成浪费。

一个牛逼的转化是倒过来做,考虑每个竹子的高度变化曲线,把末端拔高到二分的值 x,倒着向前看是否满足 hi

这样有什么好处呢,可以发现砍掉就不会浪费了,因为变成拔高,每天降低 ai,那么就是直接拿堆贪心,因为竹子高度不能变成 0,因此直接维护最快变成 0 的那个搞,如果一个竹子满足最后高度已经大于 hi 就扔掉。

code


ARC087F *3252

有一棵 n 个点的树,定义一个排列 p 的价值为 dis(i,pi),求有多少个排列满足价值最大。

n5000

不是什么难题。

考虑那个树上匹配的东西是一个经典结论,也就是对于每条边统计答案即可。

考虑把重心变成根,这样每条边的贡献就是子树大小了。

想要满足是最大值,也就是对于根的几个儿子而言,每个点都需要连到另一个子树里去。

这个想了半天 dp 不会,结果可以直接容斥,考虑有多少个树在子树里自己匹配,然后直接跑个背包合并即可。

code


ARC135E *3157

有一个长度为 n 的序列,满足。

  • a1=X
  • aii 的倍数
  • ai>ai1(i2)

现在已知 n,X,求 i=1nai 的最小值对 998244353 取模后的结果。

n,X1018

这场比赛的时候还在某亮。。。当时过了 ABC 分成两组分别做D,E,我去了 D,结果他们做 E 的找了1.5h 的规律也没找出来。。

很显然有一个 O(n) 的暴力递推。

ai=iai1i+i

这个递推巨难做,好像没有什么可以优化的空间。

考虑设 bi=aii

那么 ibi<(i+1)bi+1,显然 bibi+1,因为取 bi+1=bi 是必然可行。

前面的式子移项,可以得到 ii+1bi<bi+1

那么

bibii+1<bi+1

然后考虑一个 X 的做法,就是说对于 iX 的部分直接暴力,大于的部分可以发现在 i=X 时,ai 的最大值为 X+j=1ij ,是 X 级别的,所以 biX 级别的,那么 bii+1 自然在后面就 <1 了,所以后面的地方 bi 全部相等,可以直接算,这样复杂度就是 O(X) 的。

此时考虑 iX3 处的取值,可以发现 bii+1X3 级别的,然后容易发现 bii+1 是单调不增的,取值只有 n3 个。

然后可以愉快地二分了,对于一个左端点,考虑它的右端点,可以假设这个左端点到右端点 bii+1 的取值全部相等,这样可以得到 br 的取值,然后判断 brr+1 是否合法即可,容易发现如果 r 在区间外一定不合法,然后区间就可以直接等差数列求和了,这个求和其实很阿拉丁。

总复杂度 X3logn,好像可以把 logn 去掉。

code

posted @   houzhiyuan  阅读(92)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 阿里最新开源QwQ-32B,效果媲美deepseek-r1满血版,部署成本又又又降低了!
· 单线程的Redis速度为什么快?
· SQL Server 2025 AI相关能力初探
· AI编程工具终极对决:字节Trae VS Cursor,谁才是开发者新宠?
· 展开说说关于C#中ORM框架的用法!
点击右上角即可分享
微信分享提示
主题色彩