日记

日记

周四 10月 16 2025
1054 字 · 5 分钟

山重水复疑无路,柳暗花明又一村。

也许马上就柳暗花明了呢?

La Vaca Saturno Saturnita

鉴定为 CF 评测机神力,时间复杂度 O(nnlog2n)O(n \sqrt{n} \log^2 n)

设当前位置为 ll,我们枚举当前 kk 的每个因子,然后二分找到下一个最近因子出现的位置 nxtnxt,那么 ansans 就要加上 (nxtl)×k(nxt - l) \times k,然后 kk 除以 anxta_{nxt},将 ll 赋值成 nxtnxt 后,开启新一轮的轮回。

时间复杂度里一个 nn 来自 nn 个查询,一个 n\sqrt{n} 来自 n\sqrt{n} 个因数,剩下的两个 log\log 来自二分查找和需要跳 logk\log k 次。因为因数个数远远没有 n\sqrt{n} 个,他也不会实打实的跳 log2n\log_2 n 次,所以应该算是非常小的常数了,能卡着时限过。

Easy Demon Problem

确实是 Easy。

发现 x=(sumaar)(sumbbc)x = (suma - a_r)(sumb - b_c)。直接枚举 x=u×vx = u \times v,看看 aa 里有没有 sumausuma - u 或者 sumavsuma - vbb 也是同理,如果都有就是 YES,如果对于所有的 u×v=xu \times v = x 都没有,那就是 NO

Zapina

简单计数 dp,鉴定为涨信心题。

dpi,j,0/1dp_{i,j,0 / 1} 表示已经分了 ii 个人,一共用了 jj 本书,有没有人高兴。

转移方程也是十分的简单。枚举下一个人分配的书数量,有 dpi+1,j+x,k[x=i+1]dpi,j,k×(njx)dp_{i + 1,j + x,k \lor [x = i + 1]} \gets dp_{i,j,k} \times \binom{n - j}{x}。然后这个组合数是因为这 nn 本书是互相区分的。

制杖题

我是制杖。

一眼容斥,但是需要注意的是:对于前三个点,它的 nn 能开到 10710^7,所以记得数组开大点。

Modulo Permutations

不是所有的计数题都用容斥

我们经过一番手玩,发现这个序列旋转后一定能变成两个单调递减的子串拼起来。一个子串的结尾是 11,另一个是 22。我们钦定 11 结尾的子串在前,那么这个序列就形如 {a1,a2,,ax,1,ax+1,ax+2,,an2,2}\{a_1,a_2,\dots,a_x,1,a_{x + 1},a_{x + 2},\dots,a_{n - 2},2\}

观察到题意里说的这是一个排列,那么我们设 bi[1,2]b_i \in [1,2] 表示 ii 在以 bib_i 结尾的子串里,那么这个 bb 一定是由一堆极长的,只由 1122 组成的子串构成。设 dpi,1/2dp_{i,1/2} 表示考虑 1i1 \sim ibi=1/2b_i = 1/2 的方案数,初始有 dp1,1=dp2,2=1dp_{1,1} = dp_{2,2} = 1

考虑如何转移。我们发现这个极长子串内一定是合法的,因为 imod(i1)=12i \mod (i - 1) = 1 \le 2。转移时枚举 jj 作为下一段开头,我们只用考虑 jmod(i1)j \mod (i - 1) 是否 2\le 2就是了。

我们枚举 i1i - 1 的倍数并加上余数进行转移,最终的答案就是 ans=n(i=1n(dpi,1+dpi,2)1)ans = n(\sum_{i = 1}^{n}(dp_{i,1} + dp_{i,2}) - 1)。减一是因为 1,21,2 都存在,dp1,1dp_{1,1}dp2,2dp_{2,2} 必然有一个不能延续到末尾。乘 nn 是因为 nn 个点都可以作为环的起点。

时间复杂度 O(n)O(n)

众数 II

今天的重量级选手来了。

设展开后的数组叫 bb。我们发现 xx 能成为众数当且仅当 bl=xb_l = x 且每个区间的结尾都 x\ge x。所以我们可以写出 O(n2V)O(n^2V) 暴力:

for (int x = 2; x <= V; x++)
for (int i = 1; i <= n; i++)
for (int j = i; j <= n && a[j] >= x; j++)
ans = (ans + a[j] - x + 1) % mod;

对于贡献为 11 的,我们记录所有贡献不为 11 的区间数,剩下的就是贡献为 11 的区间数了。

考虑优化。我们发现在 x,jx,j 固定的情况下,ajx+1a_j - x + 1 也固定,所以我们可以这样:

for (int x = 2; x <= V; x++)
{
for (int i = 1; i <= n; i++)
{
if (a[i] < x)
continue;
int p = i;
while (a[p + 1] >= x)
p++;
for (int j = i; j <= p; j++)
ans = (ans + (a[p] - x + 1) * (p - i + 1)) % mod;
}
}

复杂度 O(nV)O(nV)

然后就是一大堆乱七八糟的推式子,建议直接阅读原文

后日谈

我能等到柳暗花明的那一天吗?


Thanks for reading!

日记

周四 10月 16 2025
1054 字 · 5 分钟