Codeforces Round #422(Div 2)

A

=w=

B

QvQ

C

题意:

有n条线段(n<=2e5)

每条线段有左端点li,右端点ri,价值cost(1<=li<=ri<=2e5,cost<=1e9)

对于一个给定的x(x<=2e5),寻找两个不相交的线段,使它们的长度和恰好为x,并且价值和最小

分析:

想法肯定是枚举一个线段,然后去check剩余长度的线段中cost最小的那个

但是有一个限制条件,就是线段不能相交

我们可以先对这些时间点进行从小到大排序

dp[i]表示当前长度为i的线段cost的最小值

那么去遍历时间点,如果当前是左端点,那么枚举这个左端点作为答案,去check dp[x-len];如果当前是右端点,那么将对应的线段更新dp数组

这样就不会有线段交叉了

D

题意:

主要是要算f(l)~f(r) (l<=r<=5e6)

f(n)表示将n个人打比赛,最少需要多少次比较(具体看原题)

分析:

可以证明对于n,分成p个人一组,那么p一定是质数时候最优

所以就可以枚举n的所有质因数做dp

此题先要线性筛,然后记录下minfactor[x]表示x的最小质因数

那么对一个数n进行分解质因数的时候,就不断除以minfactor就行了(之前本蒟蒻分解质因数都是试除……吼菜啊……)

E

题意:

长度<=1e5的字符串s和t和一个整数x(x<=30)

问是否能够从s中按顺序挑出若干个子段,拼起来可以凑成t(个数<=x)

分析:

想到dp

dp[pres][pret]表示s串前pres个凑成t串pret个最少需要多少多少个子段

这样明显会MLE TLE

子段数很小,状态的描述又只围绕它们三个,所以可以将子段数作为状态

dp[i][j]表示s串前i个,挑出j段能最多拼出t串的前多少位

dp[i][j]=u

那么可以转移到两种状态:

①dp[i+1][j]=dp[i][j]

②dp[i+lcp][j+1]=u+lcp

如何快速计算lcp呢?

这就是后缀数组的经典应用拉

原文地址:https://www.cnblogs.com/wmrv587/p/7113209.html