7.24前.模拟赛部分题目总结

还是太蒻了...

模拟4:

1.B&B
原题在这里
构造题,题目描述挺清晰的.
这种题一般要先满足其中一个性质,再在该性质不变的前提下尽量满足另一个限制.
在我们直接进行构造一个递增序列,然后把A序列做一个前缀和再作一个后缀和,使之满足和=+1/-1.
前缀只能减小,后缀只能增加,这样满足递增性质.
这样这个前后缀整体进行变换就能实现变换加和大小的效果.
2.W&W

赛时有一种正解打法,构建状态\(f_{i,k}\)表示上个区间取模之后值为k,划分了i个区间.
因为有取模,所以情况分两种,一种取模后比当前需要更新点取模后值大,反之则小.
用两个线段树分别维护起来,然后对不同情况用两个线段树查询一下.
外层循环k每一次清空线段树,只留k个点分k-1区间的情况,再从n-k更新答案.
复杂度\(O(n×k×log(p))\),考场上没调出来,且改了时限会被卡.(这种题还是树状数组好一点,常数小,好写)
赛后改思路,沿用最暴力的思路枚举i,j作为断点和划分区间数.
观察发现一个点的值一定是当前点值+p×k.
然后对前面的决策点x,y进行分析,扩展f[i][j+1],若f[x][j]<f[y][j],则x一定更优.
因为\(f_{i,j+1}->f_{x,j}+w_x≡f_{y,j}+w_y(mod\ p)\),其中\(w_x,w_y\)因为mod p所以<p.
所以这时\(f_{x,j}<=f_{y,j}\).根据这个对每个分界层j加个最优决策记录即可通过该题.\(O(n^2×k)->O(n×k)\)
3.简单的博弈

这题同题面,是博弈论的题,然而不太简单,思考对树上游戏进行划分,将每个子树游戏看成独立的.
建立SG函数,以1作为根,每个节点处观察,发现每个节点的父亲边断开,该节点都无法继续操作(看做SG值为0).
我们将每个情况看成一个状态对于树上每个边的状态之间的变换建立一个DAG.
跳出原树看问题,发现断父亲边这一情况就是每个状态向下连至一个状态SG=0的点.
将带上父亲边的节点看做是一种状态(局面),断开树上每个边跳到一个新局面,这时这是同一组游戏中,直接取mex满足性质.
所以所有的状态SG值都要+1,我们再看原树,之前说整个树的游戏独立,现在来看为什么独立.
每个树的节点连向两个分情况,但是这两个分状态在同一游戏中无法拼成(没有父亲啊).
所以二者状态独立,直接xor.
4.舞会
有复杂度较大的区间二分法.
首先看整个区间的答案怎么统计,最直观的就是对每个区间枚举每个数去跑一遍统计答案.
这样时间复杂度爆炸,所以要优化.
考虑把区间化小,现在对于一个区间的答案,它可以由两个部分组成,一个是两个分区间的答案,一个是合区间的(跨过mid)
那么我们二分的话,明显看出其优点在于将区间分成log层支持我们以较暴力的统计方式得到答案.
所以我们直接对于所有在区间内出现的点进行暴力cnt统计.
我们以mid出发去统计两端的区间众数,因为之前的分区间答案在二分过程中已经统计过,不管.
那么从mid向左向右分别延伸,将在i位置的值出现次数记为\(c_{val_i}\),若

\[c_{val_i}>mid-l+1(i<mid)||r-mid(i>mid) \]

把这个值放入栈中(不重复放入),它可能可以扩展答案.
总共到栈中的值一定\(<=log(r-l+1)\)
这时我们再暴力枚举所有在栈中的值,对区间进行统计.
那么现在我们需要实现的是\(O(n)\)将区间答案统计完毕(外部乘上枚举栈中值的\(O(log(r-l+1))\)).
考虑朴素统计肯定是枚举l,r这是\(n^2\),那我们需要做到的就变成了固定一个l/r找到所有的合法r/l一次性统计.
将一个值在区间内部出现的次数记为\(cnt_i\).依照定义可得合法时:

\[cnt_i>\frac{r-l+1}{2} \]

现在分奇偶讨论转化原式,当原值为偶数:

\[cnt_i×2>r-l+1->cnt_i×2>=r-l+2 \]

奇数时原式应该是向上取了整后:

\[cnt_i>=\lceil\frac{r-l+1}{2}\rceil->cnt_i×2>=r-l+2 \]

发现这俩是一个式子,所以就把mid左侧依次统计枚举值出现次数放入数组中统计它(位置i)可以向右扩展到哪里(\(i+2×cnt\)).
上面这个我们只标记了它的延伸边界,所以向右的部分它也能覆盖(类似差分),所以要遍历区间覆盖点向右统计\(sum_i\).
从左贡献循环中跳出后,再从mid向右统计,它能够延伸到\(i-2×cnt\)的范围,但是观察式子,我们在这里要-2保证其为严格众数.
所以这时我们将它能够够到的最左侧答案加入统计,这样就完成了一个区间统计.\(O(nlog^2n)\)
还有其他没学会的方法,明天再补.
up:现在会了,要用到树状数组维护三维前缀和链接在这里
具体思路如下,在整个区间我们枚举众数之后,每个数分为非众数与众数两类,我们考虑维护权值\(c_i\)\(2×s_{众数}-i\)
和上面所述判断众数方式一致,当\(c_i>c_j\)时可行.
然后考虑直接用树状数组维护,可以发现每一个节点在我们枚举众数之后,时间复杂度就是\(O(n^2log\ n)\)级别的,不行.
现在考虑什么情况下贡献可以直接算,考虑到在枚举众数不出现的情况下,整个区间的权值递减。
我们观察这个递减的区间,它所能够计算的贡献为(l,r为连续递减区间左右端点,t为对应权值在前面出现的次数):

\[\sum_{i=l}^r\sum_{j=min(c_k(k<l))}^{c_i-1}t_j \]

既然连续,就可以直接对于对应权值的出现次数t维护一个二维前缀和,我们用常数较小的树状数组借助差分实现。
因为整个区间的权值范围在(-n,n)之间,所以加上一个n的偏移量维护。
一个区间统计完答案之后,在树状数组中对该区间直接修改即可。

posted @ 2024-08-09 17:15  SLS-wwppcc  阅读(37)  评论(0)    收藏  举报