题目链接:杭电多校九 - Virtual Judge
题目:
样例输入:
6 2
4 5
3 6
样例输出:
1 1
2 2
题意:给定n个点的完全图,两个点之间的距离为他们的gcd,q次询问,每次询问给出两个点,问这两个点之间的最短路以及方案数。
分析:不难发现,当询问的两个点u和v互质的时候,最短路一定是1,而且方案数也一定是1,最短路就是两个点之间的直接连边,如果两个点u和v不互质呢?经过思考发现最短路一定不会超过2,由u和v不互质可以得到u和v中任何一个数都不是1,那么从u->1->v长度就是2,所以最短路是不会比2长的,而且不难发现对于任意的x若满足gcd(u,x)=gcd(x,v)=1,那么就有u->x->v长度就是2,但是特别需要注意的一个点就是如果gcd(u,v)=2,那么u和v之间也存在这一条权值为2的直接连边,这也是一个坑点,当时考试的时候还因为这个点wa了好几发。那么问题现在就转变为求解1~n中同时与u和v互质的数的个数,这个我们显然可以用质因子容斥来做,因为对于任意的x如果同时与u和v互斥就等价于不含有u中的质因子,也不含有v中的质因子,那么就等价于1~n中去掉含有u和v的质因子的数,那么这个就可以用容斥来解决了。就是用一个数组同时记录u和v的质因子的去重后结果,然后直接对质因子进行容斥,枚举质因子的出现状态,然后就可以求解。
但是在容斥过程中有三个地方需要额外注意一下,否则容易超时。
(1)我们可以先用欧拉筛求出1~n的所有质数,然后存进prime数组里,在对u和v进行质因子分解时利用事先筛好的素数求解会更快
(2)由于容斥原理的过程是对每一个因数在1~n中出现的次数进行容斥,所以当前容斥的因数如果大于n那么就直接退出循环即可,结果是不会受到影响的。
(3)我们一般容斥枚举出现1的位置是用for循环,但是在考试时发现TLE了,于是可以用lowbit优化一下,我们用lowbit直接返回1的第一次出现的位置,然后再用log求一下位置,然后就会优化很多,剩余操作跟普通容斥相同
细节见代码:
#include
#include
#include
#include
#include