CSP模拟49
模板题、THUSC、8ady、白子说话
模板题
看似是多项式乘法模板题,实际发现最多只有 \(25\) 次询问。
那么就可以 \(O(n)\) 处理每次询问,维护一个前缀和直接处理即可,注意考虑 std::min(n,r - j) + j < l
的情况,这种情况不能计算贡献。
还有就是开 long long
。
THUSC
考虑什么时候两个值相等,
那么有
显然 \(\dfrac{x}{y}\) 的值相等的值是可以互换位置的,但是 \(\dfrac{x}{y}\) 的值相等不意味最终的权值相等。
权值和 \(\dfrac{x}{y}\) 均相等的一部分我们视为一个块,这些块内部可以互换位置,\(\dfrac{x}{y}\) 相同但权值不同的块之间不能互换位置,但块之间的相对位置可以换。
所以这部分的方案数就是各个块的方案数乘起来。
数据范围是 \(10^3\),可以直接 \(O(n^2)\) 枚举。(赛时以为数据范围 \(10^5\),恼了)
8ady
枚举要记得剪枝,搜到第 \(k\) 个就停,不然就 TLE 挂 \(20 \ \text{pts}\) 。
正解先考虑 \(O(n^3)\) 的暴力,考虑放置每一个数得到数列 \(a\)。
首先考虑一些值的位置是确定的,考虑第 \(i\) 位小于 \(1 \sim i - 1\) 位的前缀最大值。
那么显然这个数要放在第 \(i - 1\) 个数后,第 \(i-1\) 个数最靠后会放在第 \(i-1+m-1\) 个位置,那么第 \(i\) 个数要放在第 \(i+m-1\) 个位置上。
不能再往后放,因为再向后放它就不能到达第 \(i\) 个位置了。
把确定的部分记录后,剩下的部分考虑用一种类似康托展开的方式做。
先回忆康托展开:
例如要求第 \(k\) 小的排列(无特殊限制),设排列长度为 \(n\)。
假设第 \(1\) 个位置放 \(1\),那么共有 \((n-1)!\) 种方案。
若 \(k \leq (n-1)!\),那么第一个位置就确定了,去枚举第二个位置;
若 \(k > (n-1)!\),那么第一个位置不应放 \(1\),继续枚举这个位置的下一个数。
以此类推,最终填完所有位置。
这题同样是类似这种方式,但不同的是,对每个数可以放的位置有限制。
一个数最靠前可以放在哪里?它可以由第一个位置不断向后排序到达现在的位置。
最靠后这个数可以放在 \(i + m - 1\) 位上,所以一个数有 \(\min(i+m-1,n)\) 个可以放的位置。
然后依次枚举每一位填入不同数的方案数,每填入一个数,后面的数就少了一个可以放的位置。
考虑正解,由于 \(20!>10^{18}\),那么除了后 \(20\) 位外,其他位只需要按照字典序最小的方式排列,实际对字典序排名产生影响的只有最后 \(20\) 位,我们就对这最后 \(20\) 位跑 \(O(n^3)\) 的暴力就可以。
白子说话
咕咕咕。