08-10 NOIP模拟测试16
如果有修改,一定要考虑全这个修改对之前的操作的影响!
T1 mxdt没到n,后来想到,但只改了二分里的,没改特判上的,然后就死了。。。
A. Blue
一开始想到了网络流,类似蜥蜴那道题,对每个石子拆点,跑最大流。然后看到数据范围发现不可做。
后来觉得先把部分分拿到。同时也在其中得到了思路上的启发。
对于m==1,直接算每两块的间隔,看是否存在一个间隔>d,引向性质二。
对于n==L-1,最优的跳法显然是把空间平均给每只蛤。任何一只蛤少跳一块,都会让另一只蛤多跳一块,从而使答案不优。引向性质一and性质二。
当你想直逼正解的时候,不要太着急,也许部分分的思考能点开你的思路!
- 对于每一轮跳跃之间,每个青蛙每轮跳跃后的相对位置不变。
- 最优解一定存在一种方案不会浪费任何一个石子。多经过石子不会让答案变差。
之后看到答案有单调性,于是开始想二分。
验证也很自然,O(n)扫mid只青蛙每次跳跃mid块(性质一)的所有路线(性质二)是否都合法,即a[i]-a[i-mid]>=d都成立。
此时实际上所有青蛙的路线是一起验证的。如果成立,任意一只青蛙都能找到自己的合法路线而不干扰其他。
这题做法挺多的:比如二分套贪心(上面O(nlogm)),单调指针维护青蛙群(wd lyl) O(n),平衡树贪心最大合法后继暴跳(skyh) O(mlogn)。
B. Weed
这题yzh学长讲过,然而我并没听懂。
只会打30分的模拟+20分的骗分。
对于20分的骗分,用树状数组倒悬打飞机维护后缀和,然后对于每个操作1用平衡树维护,每次直接查平衡树中最小的点在树状数组中的前缀即可。
正解:用线段树按时间维护所有操作。引入三个标记,add,del,val,表示我这个区间向外表现add个0操作,del个1操作,所有0操作的权值和。每次up,由于时间顺序,考虑右区间的1操作对左区间的0操作影响,分类讨论。
- 当L.add<=R.del时,右区间把左区间删光,K.add=R.add,K.del=R.del-L.add(剩下的,这样能让K区间向外表现del,把剩下的要删的在前面的区间中补回来)+L.del,K.val=R.val。
- 当L.add>R.del时,左区间删不完,右区间需要在左区间内删除R.del个优先靠右的0操作,于是引入calc(k,num)函数,计算在k区间内删除后num个0操作剩余的val值和。于是有K.add=L.add-R.del+R.add,K.del=L.del,K.val=R.val+calc(L,R.del)。
关于calc()函数,也需要分类讨论:
- 当num==R.add时,返回K.val-R.val
- 当num<R.add时,左区间全部留下,递归在右区间里找num个,返回K.val-R.val+calc(R,num)
- 当num>R.add时,左区间部分留下,右区间全部删掉R.add个,需要在左区间里再找num-R.add+R.del,返回calc()
C. Drink