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呢?
这就是后缀数组的经典应用拉