1006
签到 ZRC 记忆化搜索(可直接模拟
1003
签到 LYF 猜结论
1007
“rnm 退钱”
签到 构造 ZRC&LYF
没啥好说的,出题人欺负我英语不好,样例给的还是1呜呜呜
下次看到这种不明不白的样例就得觉得有坑
补1009
题意:
问1e6的数列中,存在 出现频率大于一半的众数的区间数有多少个。值域1e6
解:
先讲一讲赛场上的思路吧
首先因为数据范围很大,就感觉像是O(n)题。同时可以想到一个O(n)的做法Boyer-Moore 投票算法。但是不知道怎么用上去。
曾经碰到过一些随机选择位置统计概率的题,显然这里要求的是准确的区间数,而不是判定性问题,没法做。
那就从暴力开始思考:
- O(n)枚举起始位置,做n遍Moore投票算法,途中记录每个数的出现次数,每次查询投票算法中的当前数是否出现次数大于一半。总复杂度$O(n^2)$
- 设一共出现了k种数,遍历每一种数,每一次把这种数看成+1,其它数看成-1,对它跑一遍$O(n\lg n)$的扫描。权值线段树或树状数组可以解决。总复杂度$O(kn\lg n)$
- 分块,对出现次数小于$\sqrt{n}$的和大于的分别处理。比赛时没有细想,因为铁定过不了。题解说这样复杂度是$O(n^\frac{3}{2}\lg n+n^\frac{3}{2})$的,可以通过调整块大小将两者均摊到$O(n^{\frac{3}{2}}\sqrt{\lg n})$
- 类似2的做法,拿权值线段树来维护前缀和。统计答案时统计有多少位置的前缀和比当前位置小。但是这样处理难以统计右端点不在+1上的答案,暴力统计的话复杂度又会和方法2一样
- 类似4的做法,用树套树维护,还没想清楚是否真的能做,但超高的复杂度$O(n\lg^2n)$和更高的代码难度让人望而却步
于是就gg了
首先考虑方法4的直接优化:
定义$a[x]$的含义为 值为$x$的位置有$a[x]$个。则对$a[x]$的区间加等价于对其差分数组$c[x]$的单点修改。同时定义$a[x]$的前缀和数组为$s[x]$,$s[x]$的前缀和数组为$g[x]$
将-1看成一段一段的连续段,则这其中产生的答案应当等于$s[x]$的区间和,等价于为$g[x]$的单点求值问题。
一段-1产生的修改为对$a[x]$的区间加,即对$c[x]$的单点加。
考虑魔改树状数组(类似区间树状数组的模式),使其得以查询$c[x]$的前缀和的前缀和的前缀和
首先树状数组自己就能解决一维,毕竟本来树状数组就是拿来搞前缀和的
$$
g[n]=\sum _ {m=1} ^ n a[m]\cdot \frac{(2+n-m)(n-m+1)}{2}\\
=\frac{(n+1)(n+2)}{2}\sum _ {m=1} ^ n a[m]-\frac{1}{2}\sum _ {m=1} ^ n 2nm\cdot a[m]+\frac{1}{2} \sum _ {m=1} ^ n m^2\cdot a[m]-\frac{1}{2}\sum _ {m=1} ^ n 3m\cdot a[m]\\
=\frac{(n+1)(n+2)}{2}\sum _ {m=1} ^ n a[m]+\frac{1}{2} \sum _ {m=1} ^ n m^2\cdot a[m]-\frac{1}{2}\sum _ {m=1} ^ n (2n+3)m\cdot a[m]
$$
维护三个树状数组即可。
考虑方法4的利用题目性质的优化:
可以发现一共最多只有$O(n)$个-1位置作为右端点时会产生答案(考试时候主要就是没想到这个)。只需要维护区间加和区间和,容易在线段树上维护。然而卡常。
能过的正解主要是两种:
- 用区间树状数组维护上面的方法4
1 | //by Richard |
- 差分+前缀和。正解1可以被优化。具体看std吧(有了上面的树状数组做法其实很显然)
1 |
|