第三场模拟。
100+95+45
第二题判无解的情况考虑到了,但是细节有一点问题。
第三题打的是暴力,没有考虑答案在模意义下会有负数,还有45分真是庆幸。
T1
题目大意:
给出一个字符串,对每个前缀按字典序排序得到数组rank[],每个前缀的长度数组len[],求Σlen[i]*rank[i]
题解:
可以发现长度为i的前缀rank就是i嘛,求1~len的平方和就好啦。
T2
题目大意:
给出n个区间,必须选出m个,求选出区间的公共部分的最大长度,并输出某一方案。
题解:
想到答案的左端点一定是某一个区间的左端点,右端点也肯定是某个区间的右端点,那么我们就可以得到一个做法。
按顺序枚举左端点,并将包含当前左端点的区间全部加入,对于这些区间的右端点排序,只保留前m大,第m大的位置就是当前左端点作为答案时对应的右端点了。
直接搞是O(n^2logn)的,很不优秀。
考虑优化,一个区间会被加入,当且仅当它的左端点小于等于当前枚举的左端点。
一个区间会永久失效,当且仅当它的右端点已经小于当前枚举的左端点。
我们搞一个小根堆,维护区间们的右端点。
每当枚举一个左端点,一些区间会被踢掉,然后堆只保留至多m个元素。
复杂度美得不行。
T3
题目大意:
有n个话题,m个学生,每个学生有感兴趣的某几个话题,状态为si(二进制表示下一个学生感兴趣话题的集合)。
某人要选择一个话题,进行k天的交流,每天的交流可以选择任意不少于1个学生,使得选取的人都对某人选择的话题感兴趣。
求某人选择学生的方案数。
两个选择学生的方案数不同当且仅当某天选择的学生集合不同。
题解:
考虑一个暴力。
每次选取一个话题集合,找出所有对这个话题集合感兴趣的学生,设人数为x,贡献为(-1)^(选取话题集合的话题个数)*x^k
复杂度是O(2^n*m)真的很不优美。
考虑优化。
我们发现每个学生只会对自己感兴趣的话题的子集造成人数+1的贡献。
我们可以预处理一下。
这样复杂度就降下来了。
据说有FWT做法,然而我不会呢。