2023年多校联训NOIP层测试3

· · 个人记录

良心场。

T1 数列变换(trans)

诈骗题。

题意:维护多次高维前缀和与差分,最后输出序列的每个元素对 998244353 取模后的值。

思路:众所周知,差分可以当做是前缀和的逆运算,具体的, 令 b_i=\begin{cases}a_i-a_{i-1}&x\in[2,n]\\a_1&i=1\end{cases},则有:

所以抵消掉次数后直接跑即可,注意负数取模的处理。

Extend.

T2 超级质数(super)

板子题。

题意:n 组询问,求 [l,r] 内各位数字互不相同的质数的个数(n \le 10^5;l,r\le4\times10^7)。

赛时看到这题空间 64MB,一看数组开不下,以为正解是数位DP,果断选择分块打表。压缩了半天字符集,结果 TLE 20pts。赛后听 bdfs_then_csdn 讲题才意识到 int 数组只需要开到 \pi(n),这下消愁了。

思路:预处理所有合法质数,二分回答每个询问即可。

T3 区间加和(sum)

题意:有一条从 1 到正无穷的数轴,初始每个整数均有一个为 0 的权值。 进行 n 次操作如下:

```cpp while (n--) { int op; ll k; cin >> op >> k; if (op == 1) v.insert(lower_bound(all(v), k), k); else { if (!v.size()) { cout << 0 << '\n'; continue; } ll ans = 0; for (auto it = v.begin(); it != v.end() && *it < k; it++) { ans += __lg(k - *it); } cout << ans << '\n'; } } ``` ## T4 距离序列(dseq) 题意:求满足以下所有条件的长度为 $n$ 的整数序列的个数,对 $998244353$ 取模。 - $1\le a_i\le m(1 \le i \le n) ```cpp void dfs(int now) { if (now == n) { bool f = true; for(int i = 0; i < n - 1; i++) if (abs(res[i] - res[i + 1]) < k) { f = false; break; } ans += f; return; } for (int i = 1; i <= m; i++) { if (now != 0 && abs(i - res[res.size() - 1]) < k) continue; res.emplace_back(i); dfs(now + 1); res.pop_back(); } } ``` 总结:要清楚知道板子中每一句话的意义(刚重修完差分,xrlong正重修线性筛)。看清楚题再写。