20210817K 复盘

都看出来做法了,但是终究没有拿到分

s2oj559 A.魔力

发现我们只让所有字符出现次数相同即可

考虑到若 \(suma[r] - suma[l-1] = sumb[r] - sumb[l-1]\)​,
\(suma[r] - sumb[r] = suma[l-1]- sumb[l-1]\)

这样,将 52 种字符开一个桶,桶的前后做差分构成一个 "特征序列",查找前面有多少个等于这个序列的位置即可

将 vector 或者 valarray 扔进去会超时,考虑 hash 这个序列

然后写 hash,遂被卡 + 超时...100 -> 80 -> 75 需要注意的是:

  • 直接自然溢出啥事没有,使用模数多半超时且被卡
  • unsigned long long 配合 unordered_map 开桶要比开 multiset 再 count 快无数倍。不知道为什么。

ywk 实现了一个巧妙的随机化方法:

  • 考虑到,若 \([l,\ r]\) 是一个满足要求的子串,那么对于它们的桶来说,一定是:每个桶都差相等的次数,画在条形图上相当于是砍掉了最底下的几层

所以给每一种不同的字符分配一个随机键值,令一个模数 P 为所有不同字符的键值和

然后实时维护桶内所有字母的键值和,让他 %P,这样就相当于是构造了一种方法,使得两个 "每个桶都差相等次数" 的数对 hash 值相同,这样再开 unordered_map 记录即可

代码简单,稍微有点看脸

s2oj560. B.粒子

考场上想一想,哦,不会做,只会枚举。又想一想,哦,这可以二分,\(k\) 很小,差不多就过了

然后写写写,测样例无锅。考完评测发现挂了,100 -> 25,莫名其妙 re,应该是访问负下标了

写实数二分的时候一定要注意的

  • 习惯性 #define double long double。实数精度误差在二分过程中是很致命的,精度不够,可能左右指针永远都不能到达相差 eps 之内,然后就 t 了。
  • check 一定要简单,一定不能写复杂,不能想复杂,尝试使用最简单不易错的方式 check,由于二分过程玄学,逻辑稍微复杂就很可能导致玄学锅,死活不明真相,浪费时间

s2oj561. C.六

考场思考出来一种状压方法,压 \(f[i][S]\) 表示,填长度为 i 的序列,每一种质因子出现情况(0,1,>1 次)为 \(S\)

然后根据这个用剩下能用的质因子 dfs 出来一个因数然后转移上去方案数。答案取 \(\sum f[i][*]\)

写写写,到 11:40 左右测样例发现过不去,怪了。然后查错,没查出来,最后无果。可能是做法假了?至今不明


wgx 使用 __int128 递归求解(__int128 可以换成 bitset):

我们将 n 的所有因数按照 "质因子 \(p_i\)​​​ 有没有出现" 分为 \(2^{质因子个数}\)​​​ 类。设状态 \(f[S]\)​​​ 表示,从 \(S\)​​ 这个状态开始填的方案数,答案取 \(f(0)\)​​。\(S\)​ 记录所有的 \(2^{质因子个数}\)​ 类的数被冲突了 0, 1, >1 次的情况

考虑枚举一个还能放的类别 i ,然后枚举和这个类别冲突的类,它们会被多冲突一次,更新状态

相当于我们希望多填一个 i 类别中的数,但是具体能放多少种数呢?这就需要在对 n 质因分解的时候乘法原理一下

由于最多有 6 个质因子,每个情况用 4 进制存,恰好需要 \(2\cdot 2^6 = 128\) 位空间,用 __uint128_t 即可

s2oj623. D.多重集合问题

ZJOI 经典整体二分板子。整体二分过程中线段树一下,注意别锅了就行。

posted @ 2021-08-17 21:49  熹圜  阅读(15)  评论(0)    收藏  举报