胡策篇题解

Posted Rabbit House~❤

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了胡策篇题解相关的知识,希望对你有一定的参考价值。

和泉纱雾与烟花大会


题目来源: UOJ 192 最强跳蚤 (只改了数据范围)
官方题解: 在这里哦~(说的很详细了 我都没啥好说的了)
题目大意: 求树上各边权乘积是完全平方数的路径数量.

这种从\\(n^2\\)条路径中找出满足xx条件的路径的条数的题, 我们可以根据常识判断要用到点分治.
不过这题并没有用到点分治, 这个一会再说, 我们先来看部分分.

哎呀其实这题好多部分分我都不会写(捂脸

算法1:

直接乘边权处理显然是不行哒, 怕是\\(w\\leq2\\)怕是都要用到高精度了(什么你说\\(w\\leq1\\), 那还用做嘛←_←)
所以我们考虑每个质因子\\(p\\), 我们要保证它的出现次数是偶数.

我们就可以预处理每个\\(w\\)的质因数分解, 然后从每个点开始dfs, 用map存一下每个质数出现的次数, 最后统计一波答案.
这样应该是时间复杂度\\(O(n^2log^2n)\\), 空间复杂度\\(O(nlogn)\\)的, 期望得分30分.(然而由于部分分不一样大概只能拿到20分, 少的这10分去找验题人要吧..)

算法2: (窝不会写)

我们把\\(w\\)质因数分解,每个出现过的质数离散化一下,可以发现至多出现\\(O(nlogn)\\)个不同的质数(事实上当\\(\\frac{w}{n}\\)不是很大的时候这个数目是\\(O(n)\\)的)。
那么使用bitset维护每个质数的出现次数,再dfs就可以做到\\(O(\\frac {n^3}{32})\\)了,但是这样并不能跑出\\(n=3000\\),事实上我们直接对离散化之后的质数开桶统计就能做到\\(O(nlog^2n)\\)了,期望得分50分。

算法3:

对于\\(w<=100\\)的点, 质数的个数不会超过32个, 所以我们就预处理质数然后状态压缩一下, 用\\(2^{i-1}\\)来记录第\\(i\\)个质数, 然后从根开始dfs一波, 然后对每一位出现过就xor一下, 如果出现次数是偶数最后xor起来一定是0.

我们最后跑出来的每个点会有一个\\(d_i\\), 我们可以知道, u xor v=0, 当且仅当u=v, 我们就sort一遍 然后统计相同的就行了.
期望得分20分. 结合算法2期望得分60分.

算法4:

算法3已经很接近正解了. 我们考虑把\\(1\\sim10^8\\)的每个质数hash成一个long long范围内的数, 然后像算法3一样从根一路异或即可. 质因数分解的话我们就预处理出\\(10^4\\)以内的质数, 然后暴力分解就行了.

时间复杂度大概是\\(O(\\sqrt w+n\\pi(w)+nlogn)\\)的, 期望得分100分.


如果能一眼A掉这道题目名称很长的水题就好了

我觉得题目名说的很对.
题目来源: codeforces938G Shortest Path Queries (挺新的比赛, 我都怕你萌做过..
(就是把数据范围从20W改成了10W, 求最小改成了求最大, 别的没了...)
官方题解: 就是找Tutorial啊 (好像是个题解讲的都比我好= =)
题目大意: 支持删边加边, 查询无向图上两个点之间异或最长路.

算法1:

\\(n,m,q\\leq10\\)的数据是让大家解放天性的... 其实出题人并不知道有什么优美的解决方式... 期望得分10分.

算法2:

任意时刻, 地图是一棵树的话很显然不可能删边加边, 所以就是只有查询. 而树上两点的路径是唯一的.
所以这个部分分就是... 让我们异或吧...
期望得分15分. 结合算法1, 期望得分25分.

算法3:

只有查询的话就是WC2011 XOR了.
随便找一棵生成树, 然后用线性基维护所有环即可.
期望得分40分. 结合算法1, 期望得分50分.

算法4:

其实我们发现扫一遍最多是\\(O(mlogc)\\)的... 所以我们遇到1,2操作可以暴力重构图跑..
时间复杂度\\(O(q_{1,2}mlogc)\\), 期望得分60分.

算法5:

没有删除的时候我们可以发现, 每个插入的边都是环边, 直接扔到线性基里处理就完了.
结合算法4, 期望得分70分.

算法6:

没有插入的时候, 按照套路倒过来做变删除为插入就行了.
结合算法5, 期望得分80分.

算法7:

都80部分分了写什么正解啊.
我们可以一眼看出我们要用动态树来维护开始时候生成树的形态, 用线性基动态维护环.
但是好像并不可做吧.

这题可以离线啊! (其实用算法6的时候就发现了OvO)
我们对时间建线段树, 某个时间段存在某条边就相当于做区间加, 查询就相当于另一个标记的单点加.
我们先完成这些区间加和单点加, 然后从顶开始dfs线段树, 遇到区间加就加上这条边, 遇到叶子节点就处理所有询问, 从一个子树中出来的时候再回滚我们做过的操作(好好想想你过去的所作所为)就行了.
至于维护树的时候, 可以采用并查集来做到优秀的复杂度, 但是要回滚所以不能做路径压缩, 只能按秩合并.

时间复杂度大概是\\(O(qlogq(logn+logc))\\)的吧, 反正是可以过了.


薇尔莉特·伊芙加登

题目来源:SPOJ DIVCNT2 Counting Divisors(square)
(原题数据范围实在是撑不住.... 所以还是缩小了...)
题目大意: 求

\\[ans=\\sum_{i=1}^nd(\\sum_{j=1}^i2j-1) \\]

其中\\(d(x)\\)表示\\(x\\)的约数个数.

直接按照题意模拟应该是没分的.
可以很轻易地看出\\(\\sum_{j=1}^i2j-1=i^2\\).
所以要求的其实是\\(ans=\\sum_{i=1}^nd(i^2)\\). (其实这才是原题嘛).
这种东西求前缀和的话, 我会杜教筛!
不过这题似乎并不用杜教筛, 不过复杂度分析的时候用到了和杜教筛同样的方法.
还是先看看部分分.

算法1:

暴力把\\(d\\)筛到\\(i^2\\), 统计答案.
时间复杂度\\(O(n^2)\\), 期望得分20分.

算法2:

这个平方很烦, 我们看一下能不能用其它式子表示\\(d(x^2)\\). 我们令

\\[x=\\prod_{i}p_i^{k_i} \\]

那么

\\[x^2=\\prod_{i}p_i^{2k_i} \\]

我们要枚举\\(x^2\\)的约数的时候, 可以枚举\\(i\\)的约数, 然后对于每个约数

\\[x\'=\\prod_{i}p_i^{k_i\'} \\]

我们可以对于每个\\(p_i\\)都分别乘上\\(k_i\\), 就成为了\\(i^2\\)的因子. 所以

\\[d(x^2)=\\sum_{d|x}2^{\\pi(d)} \\]

这个\\(2^{\\pi(d)}\\)是个啥东西呢? 我们可以把它视为\\(d\\)的每个质因子选0个或者1个之后乘起来得到的\\(d\\)的因数的个数. 也可以说是\\(d\\)的无平方因子的个数.
我们还可以惊奇的发现, 无平方因子的\\(\\mu\\)都是-1或1的, 而有平方因子的\\(\\mu\\)都是0, 所以我们可以视为对\\(d\\)的每个因子\\(t\\)\\(\\mu^2\\)求个和.

\\[d(x^2)=\\sum_{d|x}2^{\\pi(d)}=\\sum_{d|x}\\sum_{t|d}\\mu^2(t) \\]

这样暴力枚举的话大概是\\(O(nlnn)\\)的吧.
期望得分40分.

算法3:

我们发现上面这个式子可以写成狄利克雷卷积的形式...

\\[d(x^2)=\\sum_{d|x}\\sum_{t|d}\\mu^2(t)=\\sum_{d|x}(\\mu^2*1)(d)=((\\mu^2*1)*1)(x)=(\\mu^2*(1*1))(x)=(\\mu^2*d)(x) \\]

这玩意显然是个积性函数, 找个规律线筛即可.
或者还可以化一下式子:

\\[ans=\\sum_{i=1}^nd(i^2)=\\sum_{i=1}^n(\\mu^2*d)(i)=\\sum_{i=1}^n\\sum_{d|i}\\mu^2(d)d(\\frac id)=\\sum_{d=1}^n\\mu^2(d)\\sum_{t=1}^{\\left \\lfloor \\frac nd \\right \\rfloor}d(t) \\]

线筛到\\(n\\)然后分块求就行了. 时间复杂度\\(O(n)\\), 期望得分70分.

算法4:

我们看到这个式子

\\[ans=\\sum_{d=1}^n\\mu^2(d)\\sum_{t=1}^{\\left \\lfloor \\frac nd \\right \\rfloor}d(t) \\]

其中这个\\(\\mu^2\\)的前缀和我们可以\\(\\sqrt n\\)的复杂度内算出来.
为什么呢, 因为有来自bzoj2440的这个式子:

\\[\\sum_{i=1}^n\\mu^2(i)=\\sum_{i=1}^{\\left \\lfloor \\sqrt n \\right \\rfloor}\\mu(i){\\left \\lfloor \\frac n{i^2} \\right \\rfloor} \\]

\\[\\sum_{i=1}^nd(i)=\\sum_{i=1}^n(1*1)(i)=\\sum_{i=1}^n\\sum_{d|n}1=\\sum_{d=1}^n\\left \\lfloor \\frac nd \\right\\rfloor \\]

所以我们也可以分块在\\(O(\\sqrt n)\\)的复杂度中求出\\(d\\)的前缀和.
\\(\\mu^2\\)\\(d\\)这两个积性函数我们也可以通过线筛来\\(O(n)\\)预处理\\(O(1)\\)查询.
所以类似于杜教筛的复杂度分析方式(我不知道怎么推的式子, 不要问我QAQ)

\\[T(n)=O(k+\\sum_{i=1}^{\\frac nk}\\sqrt \\frac ni)=O(k+\\frac n{\\sqrt k}) \\]

\\(k=n^{\\frac 23}\\)的时候, 时间复杂度最优为\\(O(n^{\\frac 23})\\).
所以我们线筛预处理出\\(n^\\frac 23\\)以内的\\(\\mu^2\\)\\(d\\)的值, 然后对\\(ans\\)分块搞, 小于\\(n^\\frac23\\)的部分查表, 大的就\\(O(\\sqrt n)\\)暴力搞就行了.
还可以用map或手写hash map记忆化一下, 速度会有明显的提升.然而是因为数据原因2333

期望得分100分.

就这些咯, 完结撒花~

以上是关于胡策篇题解的主要内容,如果未能解决你的问题,请参考以下文章

题解[CH弱省胡策R2]TATT

题解——home(必经路tarjan)

bzoj5252: [2018多省省队联测]林克卡特树

BZOJ3502 PA2012 Tanie linie

STOI补番队胡策

CXMS 胡策2