[Codeforces Round #431]简要题解

时间:2021-08-06 16:48:19

来自FallDream的博客,未经允许, 请勿转载,谢谢。


好久没写cf题解了zzz

代码比较丑不贴了,cf上都可以看

Div2A.

给你一个长度为n(n<=100)的序列 判断是否可以分成奇数个长度是奇数,且第一个和最后一个都是奇数的子串

当时想都没想就交了个dp

发现实际上满足n是奇数,a1和an都是奇数即可。

Div2B

给n(n<=1000)个点,第i个点坐标(i,ai),问是否可以用两条平行线恰好穿过所有的点

有一条线肯定通过12,或者23或者13,枚举情况分别判断即可。

Div1A

将两个串合并的费用是所有字母在两边的个数的乘积之和,要求构造一个最小费用是n(<=100000)的串。

不同字母的费用分开计算,m个相同字母的费用是m(m-1)/2 贪心一下就好了。

Div1B

有n(<=100000)个点,第i个点在ti时间之后从x或者y轴的pi的位置开始向另一个轴正方向移动,两个点相撞会反弹,求每个点最终位置。

首先根据pi-ti不同分开处理

然后对于每个点求出有多少个pi-ti相同的,并且从另一个方向飞过来的点,同时求出有多少个pi-ti相同的,并且和他同一个轴的坐标比他大的点。

两种点都会让他反弹,根据哪种比较多判断最终飞的方向,可以用一个线段树查k大来获得最终位置。

Div1C

维护一个长度为n(<=100000)的序列,支持单点修改,查询区间所有权值最大位置-最小位置的和,m<=100000。

用set维护每种权值的出现位置,每个数和它的上个数都在区间内时会产生(距离)的贡献。

然后就变成了二维单点改,查询矩形和的问题,套树貌似空间不太够,cdq分治比较稳。

Div1D

题目比较复杂,可以自己看,不解释了。

可以看出这道题肯定是DP,因为一个图就等于一条边加上很多个“桥”,每个桥又由两个图组成,有重复的子问题。

用f[i][j]表示用i次操作获得一个流量是j的桥的方案数。

用g[i][j]表示用i此操作获得一个流量是j的图的方案数。

f[i][j] * f[k][l] 转移到 -> g[i+k+1][min(j,l)]

然后因为同构的关系同一个f[i][j]一起转移

从n个里选出k个,可以重复的方案数是C(n+k-1,n-1)

动态维护这个组合数,在转移的时候 枚举选择k个f[i][j],则g[i'][j']+=f[i'-k*i][j'-k*j] * C(f[i][j]+k-1,f[i][j]-1)