P2350

P2350 [HAOI2012]外星人

给定一个表示为 i=1mpiqi 的数 N
对于 N,求出 x 满足 φ(φ(φ(φ(φ(N)))))xφ()=1

根据题目中给出的提示: φ(i=1mpiqi)=i=1m(pi1)×piqi1
用语言表述就是:对于每次 φ(N) 的操作,相当于将 N 先除以其每一个质因数,再乘以每个质因数减一的值最后得到的结果。
因为每次只能将质因数减一,所以最后使得乘积为 1 的情况就是质因数 2 减一得到 1,而每次只能将一个 2 转化。
所以最终的操作次数就是每个质因数能拆出 2 的个数(也就是对于一个数,如果是奇数就减一,如果是偶数就分解质因数,最后会有多少个 2)。
考虑进行 DP 预处理。
fi 表示的是 i 能拆出 2 的个数。
则有状态转移方程式:{fi=fi1(gcd(i,j)=1)fx×y=fx+fy
最后有一个细节点:如果一开始给出的质因数中没有 2,则需要进行一次操作之后才能分解出 2,此时要把最后的答案加一。

#include <bits/stdc++.h>
using namespace std;int rd(){
	int w=0,v=1;char c=getchar();while(c<'0'||c>'9'){if(c=='-')v=-1;c=getchar();}
	while(c>='0'&&c<='9'){w=(w<<1)+(w<<3)+(c&15);c=getchar();}return w*v;
}const int N=1e5+5e4;int f[N],p[N],flag,T,n,tp,ans;bool is[N];
int main(){
	f[1]=1;for(int i=2;i<=100000;i++){
		if(!is[i])p[++tp]=i,f[i]=f[i-1];
		for(int j=1;j<=tp&&i*p[j]<=100000;j++){is[i*p[j]]=1,f[i*p[j]]=f[i]+f[p[j]];if(i==p[j])break;}
	}T=rd();while(T--){
		n=rd();ans=flag=0;for(int i=1,a,b;i<=n;i++){a=rd(),b=rd();if(a==2)flag=1;ans+=f[a]*b;}
		if(!flag)ans++;cout<<ans<<endl;
	}return 0;
}
posted @   AIskeleton  阅读(43)  评论(0编辑  收藏  举报
编辑推荐:
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 基于Microsoft.Extensions.AI核心库实现RAG应用
· Linux系列:如何用heaptrack跟踪.NET程序的非托管内存泄露
· 开发者必知的日志记录最佳实践
阅读排行:
· TypeScript + Deepseek 打造卜卦网站:技术与玄学的结合
· Manus的开源复刻OpenManus初探
· 写一个简单的SQL生成工具
· AI 智能体引爆开源社区「GitHub 热点速览」
· C#/.NET/.NET Core技术前沿周刊 | 第 29 期(2025年3.1-3.9)
点击右上角即可分享
微信分享提示