51nod1742 开心的小Q

基准时间限制:1 秒 空间限制:131072 KB 分值: 80 难度:5级算法题
 收藏
 关注
如果一个数字存在一个约数是大于1的完全平方数,那么小Q就认为这个数是有趣的。
小Q喜欢收集有趣的数字,每找到一个有趣的数,小Q就会变得很开心。
小Q发现12是有趣的,18也是有趣的,它们都是36的约数,而在36的约数中,还有3个数是有趣的,它们是4、9、36。
小Q很好奇,在a~b里每个数字各有多少个有趣的约数,由于a和b太大了,所以他只想知道这些个数之和是多少。
例如4有1个有趣的约数,8有2个有趣的约数,9有1个有趣的约数,所以1~10里每个数的有趣约数个数之和是4。
Input
输入数据包括2个数:a, b,中间用空格分隔。(1≤a≤b≤10^9)
Output
输出a~b里每个数字的有趣约数个数之和。
Input示例
1 10
Output示例
4


题解:

假题,不会。这种题我再过1年也不会做。



题解:

#include<bits/stdc++.h>
#define ll long long
using namespace std;
ll g[200001],mu[200001],a[200001],n1;
void yuchuli(){
	ll i,j;
	for(i=2;i<=100000;i++){
		if(g[i])continue;
		a[++n1]=i;
		mu[i]=-1;
		for(j=2;i*j<=100000;j++)g[i*j]=1;
	}
	mu[1]=1;
	for(i=2;2*i<=100000;i++)
	 for(j=1;j<=n1&&a[j]*i<=100000;j++){
	 	if(!(i%a[j])){
	 		mu[i*a[j]]=0;
	 		break;
		 }
		 mu[a[j]*i]=-mu[i];
	 }
}
ll F(ll n){
	if(!n)return 0;
	ll ans=n;
	for(ll i=1;i*i<=n;i++)ans-=mu[i]*(n/(i*i));
	return ans;
}
ll solve(ll x){
	ll i,ans=0,r,cnt=1;
	for(i=1;i<x&&cnt;i+=cnt){
		r=x/i;
		cnt=x/r-x/(r+1);
		ans+=cnt*F(r);
	}
	return ans;
}
int main(){
	ll n,m;
	yuchuli();
	scanf("%lld%lld",&n,&m);
	printf("%lld",solve(m)-solve(n-1));
}

阅读更多
想对作者说点什么?

博主推荐

换一批

没有更多推荐了,返回首页