2024 暑期模拟赛 #7
下次一定要认真认真认真算算动态空间了 /ll
第一次知道 set 不能指针相减 /jk
2024暑期CSP-S&NOIP模拟赛第7套
时间:3h20min (2025.11.06 18:40~22:00)
题目数:4
难度:
| A | B | C | D |
|---|---|---|---|
| \(\color{#FFC116} 黄\) | \(\color{#FFC116} 黄\) | \(\color{#3498DB} 蓝\) | \(\color{#BFBFBF} ?\) |
| *1400 | *1500 | *2100 | *? |
估分:[50,100] + 100 + 20 + 35 = [205,255]
得分:90 + 100 + 52 + 30 = 272
Rank:1/6
场祭
读题。
A 是 Boruvka?好像不会维护,看看能不能找点性质只保留少量的边。根据人类智慧,边权 \(>n\) 的边几乎不可能出现在最终的 MST 中,所以只保留边权 \(\le n\) 的边即可,保险起见开到 \(2n\)。用的是一个根号复杂度的枚举,大样例跑了 700ms,因为学校机子性能很差所以应该稳过了。
开 B,哦打表找规律题,切了。
此时只过了 1h。
开 C,不怎么会,但是发现 D 似乎可以莫队,于是去思考莫队了,但是发现不会维护,不过倒是想到了个 \(O(nq \log n)\) 的主席树做法。
就是先转化为 \(b_r > a_l > \max _{i=l+1} ^{r-1} \{a_i\}\),发现 \(a\) 的限制可以笛卡尔树预处理出来,令 \(a_i\) 能延伸到的最右端点为 \(rx_i\)。
好像挺有前途的?似乎还真可以用这个 \(O(q \sqrt n \log n)\) 莫队做,左端点就是主席树的查询,右端点就是维护一个 set 表示 \([L,R]\) 内 \(rx_i > R\) 的 \(a_i\),写写写,怎么 CE!
原来 set 不能指针相减吗 /jk
寄!(此时太急了以至于忘了可以离散化后上 BIT 了喵
没时间了打了个暴力走人了。
3h20min 还是太紧张了。
补题
草,C 只要改成非暴力就全输出 \(0\) 就能 64pts。。
A 挂的那个点是 MLE 了,枚举范围调小点就过了,下次一定要认真认真认真算算动态空间了 /ll
A 的证明:注意到连接所有 \((i,i+1)\) 时,可以得到一棵边权都 \(<n\) 的生成树,所以 MST 中边权一定 \(<n\)。
补 C,并不是很难啊,给点时间能做出大部分的。分讨:
\(\bf S=1\):
注意到与操作是一个很优秀的操作,而且起点是 \(1\),这意味着有很多点的答案都是 \(0\)。
具体地,考虑构造一个方案使得尽量多的点答案为 \(0\),发现可以先连一条 \((1 , 2^t , 0)\) 的边,其中 \(t\) 为 \(\le n\) 的最大值。然后 \(\forall i \in (1,2^t)\) 就可以直接 \((2^t,i,0)\);\(\forall i \in (2^t,n]\) 可以先走到 \(\neg i\)(\(\neg i\) 一定 \(< 2^t\))再走到 \(i\) 来实现。
但是发现有个特殊情况,就是 \(n = 2^{t+1}-1\) 的时候,\(\neg n = 0\)。需要特判一下,建一些必要的边跑个最短路即可。
\(\bf S=2\):
注意到 \((00)_2 \oplus (11)_2\) 可以拆成 \((01)_2 \oplus (11)_2\) 和 \((00)_2 \oplus (01)_2\),所以只需要建所有 \((u,v,k \cdot (u \oplus v))\) 满足 \(u,v\) 二进制下只差一位的边,直接跑最短路即可。
\(\bf S = 3\):
最难的一部分。
引理:最多只会进行一次跳跃。
Proof. 若进行了两次跳跃 \((a,b,k \cdot (a|b))\) 和 \((c,d,k \cdot (c|d))\),那么 \(a|b|c|d\) 的二进制位都会产生 \(\ge 1\) 次代价,而直接 \((a,d,k \cdot (a|d))\) 只有 \(a|d\) 的二进制位会产生 \(=1\) 代价。QED.
于是考虑这一次跳跃在什么位置,考虑 \(1 \leadsto k\) 的最短路,有下面 \(4\) 种情况(. 表示走原图上的边,连续的 - 表示跳跃的部分):
...............--------.......---------------.......--------...-----.......
#1 #2 #2 都是可以建边 \(\forall i \in (1,n] : (1,i,k \cdot (1|i))\) 再跑最短路做掉的。
考虑 #4 #5 如何最优,首先若进行跳跃,则到达 \(i\) 的跳跃代价一定 \(\ge i\)。发现如果直接从 \(1\) 跳到 \(i\),代价是 \([i,i+1]\),这已经优于大部分情况了。而其它情况能够达到代价为 \(i\) 的,那么一定是从 \(i\) 的子集跳过来。
于是在跑完第一遍最短路后,直接枚举 \(i\) 的子集并更新 \(dis_i\),就可以做掉 #4,然后再这个基础上再建边 \(\forall i \in (1,n] : (1,i,dis_i)\),再跑一边最短路,就可以做掉 #5。
但是直接枚举子集是 \(O(n^2)\) 的,需要用个 SOS dp 来做。
然后不理解的一点是,SOS dp 不显示传递为何也是正确的?不知道。问了问 gpt 还是不会。
D 是那种并非 \(q\) 次操作的 ds,题解没看懂 /yun
天依宝宝可爱!

浙公网安备 33010602011771号