CF870F

感觉完全没有 *2700

看到题,猜测 maxdis 不会很大,于是按照路径种类分类讨论一下路径 (i,j)。下设 fi 为最小质因数,并且更下面的情况不包括上面的情况。

  • gcd(i,j)>1

这种显然 dis=1,数量则为 n(i1φ(i))

  • fi×fjn

这种可以设置一个中转点为 fi×fj。路径则为 ifi×fjj

考虑怎样计数。发现对于一个 i 计算有多少个满足条件的 j<i(i,j) 不满足上面情况是困难的,但是如果不加后两个要求则是简单的,于是先算总数再减去不满足两个要求的。

计算总数可以考虑对于每个质数 x 找出最大的满足 x×yn 的质数 y。并记录一个 cnti 表示有多少个 j 满足 fj=i,再对 cnt 做一个前缀和,就可以快速计算了。

然后减去 i=jgcd(i,j)>1 的情况就行了。

  • fin2fjn2

思考发现这种的路径即为 i2×fi2×fj×j。理论上来说这种是比较难计数的,但是还是和上一种一样的思路,正难则反。所有满足上述条件的减去满足前两个条件的数量。就可以轻松解决。

需要线性筛预处理,没什么细节,具体可以参考代码。

code:

点击查看代码
int n,m,pm[N],c[N],f[N],g[N],phi[N],h[N],s[N];
bool vis[N];
void Yorushika(){
	scanf("%d",&n);
	ll sphi=0;
	rep(i,2,n){
		if(!vis[i]){
			pm[++m]=i,c[m]++;
			f[i]=i,g[i]=m,phi[i]=i-1;
		}
		rep(j,1,m){
			if(i>n/pm[j])break;
			int k=i*pm[j];
			vis[k]=1,f[k]=pm[j];
			c[g[pm[j]]]++;
			if(i%pm[j]==0){phi[k]=phi[i]*pm[j];break;}
			phi[k]=phi[i]*(pm[j]-1);
		}
		sphi+=i-1-phi[i];
	}
	int j=m;
	pm[0]=1;
	rep(i,1,m){
		while(pm[i]>n/pm[j])j--;
		h[i]=j,s[i]=s[i-1]+c[i];
	}
	ll sum=0,cnt=0;
	rep(i,2,n){
		sum+=s[h[g[f[i]]]];
		sum-=f[i]<=n/f[i];
		cnt+=f[i]<=n/2;
	}
	sum/=2,cnt=cnt*(cnt-1)/2;
	printf("%lld\n",(sum-sphi)*2+sphi+(cnt-sum)*3);
}
signed main(){
	int t=1;
	//	scanf("%d",&t);
	while(t--)
		Yorushika();
}
posted @   yinhee  阅读(5)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 分享一个免费、快速、无限量使用的满血 DeepSeek R1 模型,支持深度思考和联网搜索!
· 基于 Docker 搭建 FRP 内网穿透开源项目(很简单哒)
· ollama系列01:轻松3步本地部署deepseek,普通电脑可用
· 按钮权限的设计及实现
· 25岁的心里话

阅读目录(Content)

此页目录为空

点击右上角即可分享
微信分享提示