正题
题目链接:https://www.luogu.com.cn/problem/P2350
题目大意
给出NNN质因数分解之后的结果,求每次N=φ(N)N=\varphi(N)N=φ(N),多少次后N=1N=1N=1。
N=∏i=1mpiqi,1≤m≤2000,1≤pi≤105,1≤qi≤109N=\prod_{i=1}^mp_i^{q_i},1\leq m\leq 2000,1\leq p_i\leq 10^5,1\leq q_i\leq 10^9N=∏i=1mpiqi,1≤m≤2000,1≤pi≤105,1≤qi≤109
解题思路
我是傻逼((((
首先φ(∏i=1mpiqi)=∏i=1m(pi−1)piqi−1\varphi(\prod_{i=1}^mp_i^{q_i})=\prod_{i=1}^m(p_i-1)p_i^{q_i-1}φ(∏i=1mpiqi)=∏i=1m(pi−1)piqi−1
开始想太多了,以为传递的延迟影响很大,后来发现设因为pi−1p_i-1pi−1一定是偶数,所以把pi−1p_i-1pi−1分解后一定有222这个质因子,所以只有在NNN没有222这个质因子的情况下传递的延迟会造成一次的影响,否则都没有影响,因为222还没有抵消延迟就已经结束了。
所以我们只需要考虑每个质数能传递出多少个222,这个用线性筛可以解决因为最后更新一个质数的一定是新增的一个质因子。
code
#include<cstdio>
#include<cstring>
#include<algorithm>
using namespace std;
const int N=1e5+10,M=1e5+10;
int T,n,cnt,pri[N],f[M],v[M];
void Prime(){f[1]=1;for(int i=2;i<M;i++){if(!v[i])pri[++cnt]=i,f[i]=f[i-1];for(int j=1;j<=cnt&&i*pri[j]<M;j++){v[i*pri[j]]=1;f[i*pri[j]]=f[i]+f[pri[j]];if(i%pri[j]==0)break;}}return;
}
int main()
{Prime();scanf("%d",&T);while(T--){scanf("%d",&n);if(!n)puts("0");long long ans=1;for(int i=1;i<=n;i++){int x,w;scanf("%d%d",&x,&w);if(x==2)ans--;ans+=1ll*f[x]*w;}printf("%lld\n",ans);}return 0;
}