8.24 模拟赛(NOIP十三连测 #6)

2024--梦熊&太戈--NOIP十三连测 #6【订正】 - 比赛 - 梦熊联盟 (mna.wang)

A. Alice 的数

有显然的 \(80\) 分。但是还是用两个小时冲到了 \(100\) 分。

做法比 std 复杂。

\(100+100+100\)

题意

\(y^2\) 是距离 \(x\) 最近的完全平方数,若有不止一个最近的直接输出 \(\texttt{Game Over}\) 结束程序。定义 \(f(x) = (-1)^{y+1}y\)

\(\sum_{i=l}^r f(i)\)\(l, r \le 10^{18}\)

做法

\(\texttt{Game Over}\) 是不可能的。

显然第一步差分。问题变成求 \([1, r]\) 的答案。

打表发现 \(f(x)\)\(x\) 的系数形如:

\[\begin{matrix} x &: 1&2&3&4&5&6&7&8&9&10&11&12&13&14&15&16&17&18&19&20&\dots \\ (-1)^y&:[1&1]&[-1&-1&-1&-1]&[1&1&1&1&1&1]&[-1&-1&-1&-1&-1&-1&-1&-1]&\dots \end{matrix} \]

为了方便我们称一个极长连续段为一段,例如表中 \([7, 12]\) 就是一段。

不难发现:

  • 第奇数段中的数都是 \(1\),第偶数段中的数都是 \(-1\)

  • \(i\) 段的长度为 \(2i\)

  • \(1 \sim n\) 段的长度和:

    \[\sum_{i=1}^n 2i = 2\sum_{i=1}^ni = n(n+1) \]

  • \(n\) 段的左端点与右端点下标:

    左端点相当于前 \(1 \sim n - 1\) 段的长度和加一,右端点相当于 \(1 \sim n\) 段的长度和。分别为:

    \[[n(n-1)+1,n(n+1)] \]

  • \(n\) 段的下标和:

    根据左右端点,用等差数列求和公式即可。

    \[\dfrac{2n \times (n(n-1)+1+n(n+1))}2 = 2n^3+n \]

  • \(1 \sim n\) 段的答案(乘上了 \((-1)^{i+1}\) 的系数后的):

    \[\sum_{i=1}^n(-1)^{i+1}(2n^3+n) = 2\times \sum_{i=1}^n(-1)^{i+1}i^3 + \sum_{i=1}^n(-1)^{i+1}i \]

所以我们可以计算 \(r\) 之前有多少完整段,并用上面说的计算这些段的答案。对于剩下的一个不完整的段,等差数列直接算即可。

现在的问题是如何快速计算:

\[\begin{matrix}\sum\limits_{i=1}^n(-1)^{i+1}i^3&\sum\limits_{i=1}^n(-1)^{i+1}i \end{matrix} \]

后者是极易的。考虑计算前者:

\[s_n = 1^3-2^3+3^3-4^3+\dots+(-1)^{n+1}i^3 \]

注意到:

\[\begin{bmatrix} s_{n-1} & n^3 & n^2 & i & 1 \end{bmatrix} \times \begin{bmatrix} 1 & 0 & 0 & 0 & 0 \\ 1 & -1 & 0 & 0 & 0 \\ 0 & -3 & -1 & 0 & 0 \\ 0 & -3 & -2 & -1 & 0 \\ 0 & -1 & -1 & -1 & -1 \end{bmatrix} =\begin{bmatrix} s_n & -(n+1)^3 & -(n+1)^2 & -(n + 1) & -1 \end{bmatrix} \]

矩阵加速即可。

B. Bob 的图

\(70+55+100\)

很好的题。会计算答案,会 DAG 部分分,拼起来就是正解,为啥还不会做呢?

做法

给定一张带边权的有向图。令 \(n_i\) 表示 \(1 \rightsquigarrow i\) 的最短路方案数,\(d_{i, k}\) 表示第 \(k\)\(1 \rightsquigarrow i\) 的最短路经过的边数。求:

\[\sum_{i=1}^n\sum_{j=1}^n\sum_{k=j+1}^n d_{i,j}\times d_{i,k} \]

取模 1e9 + 7。

做法

首先

\[\sum_{j=1}^n\sum_{k=j+1}^n d_{i,j}\times d_{i,k} = \dfrac{\left(\sum_{j=1}^nd_{i,j}\right)^2-\sum_{j=1}^nd_{i,j}^2}2 \]

所以我们要维护的是 \(1 \rightsquigarrow i\) 的所有最短路的边数和,以及平方和。

建最短路 DAG。即保留所有满足 \(dis_u = dis_v+w_{u,v}\) 的边 \((u, v)\)。其中 \(dis_u\)\(1 \rightsquigarrow i\) 的最短路,用 Dijkstra 预处理。

那么在原图中求 \(1 \rightsquigarrow i\) 的所有最短路的边数和以及平方和,等价于在新图中求 \(1 \rightsquigarrow i\) 的所有路径的边数和以及平方和。

极易!令 \(f(i, u)\) 表示 \(1 \rightsquigarrow u\) 的所有路径的边数的 \(i\) 次方和。其中 \(0 \le i \le 2\)。拓扑排序转移(边 \(u \to v\)):

\[f(0,u) \to f(0,v) \\ f(0,u)+(1,u) \to f(1, v) \\ f(0,u)+2f(1,u)+f(2,u)\to f(2,v) \]

C. 维护整数列

\([60,80]+0+100\)

数据是大海。

负数取模错了导致 \(100 \to 0\)

我都能构造数据卡掉我自己但是满分了。

题意

维护数据结构,支持单点修,求区间和,求区间平方和,将区间所有数除以 \(p\) 下取整。

不保证任何值非负(除 \(n, m\) 之类的)。保证 \(p \ne 0\)。这里下取整指 C++ 中的 floor() 函数。

做法

没有负数是大水题。

除以 \(p = 1\) 相当于啥也没做,除以 \(p = -1\) 相当于区间取反(显然区间取反不会影响区间平方和)。对于除以其它的数 \(|p|\ge 2\),最多除以 \(\log\) 次后就会变成 \(0\)

普通的修改暴力。如果这个线段树节点所代表的区间内的数都是 \(0\) 则不同修改。

D. 大头问题

\(50+55+100\)

还在调。

为了观感单独开一篇文章

posted @ 2024-08-25 17:59  2huk  阅读(28)  评论(0编辑  收藏  举报