2022.07.17 zrNOI模拟赛总结
1.时间安排
8:00~8:10 看题面
T1:数学题,以前作过类似的全是9的题,但这题是全是1,不好转成同余,不过有一眼的 \(Tn^2\) 做法。
T2:可能是图上的DP题,给了20分暴搜,也许存在 \(n^3\) 的DP,本身维护次小值就不好做,这题还是图,感觉不太可做。
T3:更是数学题,给了20分 \(n^5\) DP,而且感觉DP式不太像能优化的样子,数据范围1e18可能正解是插值这类的。
8:10~8:50
写了前三题暴力分,没给大样例,为了给后面的分对拍暴力写的比较谨慎。
8:50~9:00
写了T3的 \(n^5\) DP,感觉不存在优化空间。
9:00~11:30
先写了T1 \(n^3\) 的暴力计算,拍小数据没问题。发现一维是计算等比数列可以显然优化,因为0没有逆元被坑了一会,还是发现了问题所在,细节比较多调了比较久,对拍没问题。
造了组极限数据跑了20s,忘了多测外层还有个 \(T\) (顺带把T3忽略的多测用预处理去掉了复杂度里的 \(T\) ),本来以为可以模个大质数用二维前缀和,结果发现自己的算法是算出来所以的值后统计,根本没法记录,也不好用二维数据结构维护。
发现一个瓶颈在于复杂度是 \(n^2\)*快速幂,改成了预处理发现已经快了不少,跑到了1s左右,卡了卡常后就没再管。
继续思考,函数值必然成环,但是打表发现环长在一些模数仍然很大,不知道怎么做。
11:30~13:00
吃饭回来想T2,发现可以二分答案转判定,把图上小于等于当前二分值的边权值赋为0,其他的赋为1,跑最短路时1即可,这个最短路的长度是随着二分值减小而单增的,可以做。
但问题在于要跑最短路,复杂度为 \(qlog|V|(n+mlogm)\) ,2000根本跑不动,只能拿40。
想不出来复杂度怎么降,开摆。
result:
T1:40 T2:40 T3:20
2.总结
(送分场输麻了)
T1:
怕乘爆用了 long long 卡常了,改成 int 60分……
%J神场切。
正解一次询问复杂度是 \(O(\sqrt plogp)\) 的,但是我觉得J神的 \(O(\sqrt p*2^7)\) 更好理解。
发现题意可以这样转化: \(A(n)=\sum_{i=0}^{n-1}10^i\equiv 0\pmod p\)->\(9A(n)\equiv 0\pmod {9p}\)->\(10^n\equiv 1\pmod {9p}\)
所以当 \(p=2||p=5\) 答案一定是0,其他情况因为 \(\gcd(10, 9p)=1\),环长一定是 \(\phi(9p)\) 的因数,可以直接 \(O(\sqrt p)\) 求出(或者直接用bsgs,带一个hash表的复杂度)。
得到环长 \(cir\) 后,由唯一分解定理可以分解成 \(\prod_{i}p_i^{d_i}\) 的形式。
设 \(n\) 表示为 \(kx\) 的形式。(\(k, x\) 都是正整数)
考虑搜索 \(x\) 与 \(cir\) 的质因数公共部分,这是 \(O(\sqrt p)\) 的。
那么 \(k\) 的取值只能在 \(1\) 到 \(n/x\) 内选,又因为不能重复,k不能含有公共部分的因子(当然如果公共部分因子的质数相同忽略)。
因为质因数分解最多只有7个不同的,所以 \(2^7\) 容斥即可,而且严格不满,可以通过。
之后考虑 \(m\) 的取值范围,取所有的质因数指数相除上取整的最大值到上界即可。
T2:
忘记了0/1最短路可以双端队列bfs做到 \(O(m)\) 拿60分 ,输麻了(我才不会说板子题当时用spfa水过去了)。
0/1最短路的双端队列bfs做法:从起点增广,按照三角形不等式更新到达点的最短路,如果当前边权是0,把下一个点加入队首,否则加入队尾,证明考虑贪心。最长路反过来即可。
正解用到了kruskal重构树,比赛时完全没往这上面想,不过回顾kruskal重构树的性质确实应该很容易往这方面思考:从小到大加边的重构树上两叶子的lca权值等于它们在原图上所有简单路径上最大边权的最小值。
建出来kruskal重构树后,考虑每次询问还是二分答案。
每次倍增到大于等于边权的两个节点,查询两个节点对应的子树中在原图上有没有连边或有没有交集。
直接利用线段树合并维护子树内向外连接的点集即可,复杂度\(O(nlog^2n)\)。
T3:
神仙数学题,第一步转化就非常妙。
题目要求 \(\prod_{i=1}^{k}min(a_i, b_i)\) ,可以转化成 \(\sum_{x_i}[\forall_i x_i\leq a_i , x_i\leq b_i]\),(这里 \(a\),\(b\) 的要求与题目相同)。
交换枚举顺序,变成枚举 \(x\) 序列,看有多少合法的 \(a,b\) 序列,考虑枚举分给 \(x\) 的和,答案即为 \(\sum_{i=k}^{min(n, m)}C_{i-1}^{k-1}*C_{n-i+k-1}^{k-1}*C_{m-i+k-1}^{k-1}\),因为模数很小,套用lucas定理就可以拿70分了。
正解考虑lucas的过程是把要求的两个数字拆成了 \(p\) 进制数,\(p\) 的取值恰到好处,可以做。
先把式子统一成 \(\sum_{i=k}^{min(n, m)}C_{i}^{k}*C_{n-i}^{k}*C_{m-i}^{k}\),便于计算。
只会先把 \(n, m, k\) 拆成 \(p\) 进制的数,之后从低位到高位做数位DP,并记录 \(n, m\) 这两维有没有借位情况,并且在最终要求不能出现借位。
因为 \(i\) 超过范围后这个组合数计算结果为0,所以保证了正确性。
时间复杂度考虑记忆化后本质不同的状态只有6*4=24种,所以一次询问的复杂度为 \(O(24p)\)。

浙公网安备 33010602011771号