2020.09.22am
9.22 AM
|--|预期|实际|
|A|100|100|
|B|100|100|
|C|100|65|
|D|100|100|
|E|100|50|
|F|100|70|
|S|600|485|
可能水,一定菜
A 校门外的树 \(\blacktriangle\!\blacktriangledown\)
- 一道罕见的区间修改区间查询的树状数组题。
- 因为查询的是树的种数,差分是难以解决的。
- 根据题意,可以转化成这个问题:查询一个区间与目前存在区间有交集的数目。
- 而这样对于每个存在的区间分三种情况:左端点在区间内,右端点在区间内,和左右端点都在区间内。但对于第三种情况是比较难解决的。
- 所以我们考虑改下定义:求没有交集的数目
- 这样就非常好解决了。分成两种情况:左端点在区间右边和右端点在区间左侧,树状数组优化左右端点位置前缀和。
- 但由于是前缀和,左端点在区间右边又要转化为总的减去左端点在区间左侧和区间内的情况。
- 那答案就是\(总-(总-(左端点在区间左侧+左端点在区间内)-(右端点在区间左侧)=左端点在查询区间右端点左侧+右端点在查询区间左端点左侧\)
B 堆蛋糕 \(\blacktriangle\!\triangledown\)
据说好多人写了很长的贪心。- 咋不会,只写得来20来行复杂度 \(O(n)\) 的乱搞算法。
- 这道题太拉了,来做我出的加强版(没开 \(O_2\) 的 \(STL\) 堆会 \(T\) )
- 直接来解 \(k\) 层蛋糕。
- 当没有元素重复时,明显答案为 \(\left \lfloor \frac{n}{k} \right \rfloor\)
- 当只有一个元素重复,且出现次数小于\(\left \lfloor \frac{n}{k} \right \rfloor\) 时,答案不变
- 当有多个元素重复,且出现次数均小于\(\left \lfloor \frac{n}{k} \right \rfloor\) 时,答案也不变(可以每个蛋糕都有一层都为该元素)
- 当有元素出现次数大于 \(\left \lfloor \frac{n}{k} \right \rfloor\)时,答案取决于剩下的元素能凑出多少个 \(k-1\) 层的蛋糕。(很明显,每个蛋糕选定一层为重复次数大于 \(\left \lfloor \frac{n}{k} \right \rfloor\) 的元素肯定是最佳答案)
- 那么我们就可以递归解决这个问题。
- 先进行离散化,计数后进行排序。具体如下:
suan(n,1);
int suan(int m,int p){
if(num[p]==0)return 0;//种类少于k
if(num[p]>m/(k-p+1))return suan(m-num[p],p+1);//目前最大的数大于n/k
return m/(k-p+1);//没有数大于,可以理解为情况3
}
C 蚯蚓 \(\blacktriangle\!\blacktriangledown\)
- 容易想到优先队列
- 对于全部增长因为难以维护可以改成单点减少
- 每次剪成两端放进堆里会导致修改速度越来越慢而\(T\)掉
- 对于这道题有一个关键的性质:每次挑出最大的剪成的两端分别递减,那我们就可以开三个队列,分别存原长(要先排序)与剪后的两端,每次挑出其中最大的进行修改即可。
D 清点人数 \(\blacktriangle\)
- 一维树状数组,应该没什么好说的了。
E 打鼹鼠 \(\blacktriangle\!\blacktriangledown\)
- 典型的二维树状数组。(可惜输入格式写挂了)
- 据说有优化空间的方式,这个打算在之后的树状数组总结(在写了在写了)里面研究后写出。
板子:
inline void add(int x,int y,int c){
for(;x<=n;x+=x&-x)
for(int i=y;i<=n;i+=i&-i)
sz[x][i]+=c;
}
inline int ask(int x,int y){
int ans=0;
for(;x>0;x-=x&-x)
for(int i=y;i>0;i-=i&-i)
ans+=sz[x][i];
return ans;
}
ASK(x1,y1,x2,y2)=ask(x2,y2)-ask(x1-1,y2)-ask(x2,y1-1)+ask(x1-1,y1-1);
F 数列区间最大值 \(\blacktriangle\)
- 强制要求\(ST\)
- 考场上因为遗忘了 \(ST\) 怎么写只能写线段树暴力
- 实际上 \(ST\) 好想也好写···

\(\cal {Made} \ {by} \ {YuGe}\)
浙公网安备 33010602011771号