P5610 [Ynoi2013] 大学 题解
Part1.自己一开始是怎么想的
已经知道大概的解法了,花神题,就是很卡常,学习一下卡常的方法。
Part2.正解是怎样的
先简单讲一下正解:发现一个性质,每一个数字最多被除 \(O(logn)\) 次就会变成 \(1\),只需要快速知道需要修改的位置就能够做到优秀的复杂度。
存储一下一个数字的倍数的出现的地方,对于修改操作,可以lower_bound来查询修改的区间。对于不是这个数字整数倍的段可以像花神的套路一样用并查集合并。
存储位置的时候本来是用vector,但是这个东西的常数有点大,所以用动态分配内存的办法,并查集的fa也用动态内存分配好即可。
Part3.差在哪里,如何解决?
并不会几个动态分配内存池的办法,学会了。
Part4.编码的困难、调出来的错误
没有。然后就是忘记强制在线的异或了。这个会RE,积累一下。
Part5.收获有什么
动态分配内存池的写法。
指针的动态空间:*fa 代表不定长的一维数组。 *p[] 代表不定长的二维数组。可以开内存池 ncc,然后用一个指针来指 *st=ncc
。
分配的时候:
p[i]=st;
st+=cnt[i];
ji[i].fa=st;
ji[i].init(cnt[i]);
st+=cnt[i];
cnt[i]=0;
Part6.时间主要花在哪里了
学习动态分配和指针的动态数组了。