首页 > 其他 > 详细

ACM-ICPC 2018 南京赛区网络预赛 J.sum(欧拉筛)

时间:2019-03-18 00:40:51      阅读:199      评论:0      收藏:0      [点我收藏+]

题目来源:https://nanti.jisuanke.com/t/A1956

技术分享图片

 

 题意:找一个数拆成无平方因子的组合数,然后求前缀和。

解题思路:我们可以把某个数分解质因数,如果某个数可以分解出三个相同的质数那么该f(n)=0,比如8=2*2*2,  24=2*2*2*3,所以f(8)=f(24)=0;如果该数是素数那么f(n)=2;

#include<iostream>
#include<cstring>
#include<algorithm>
#include<cmath>
#include<vector>
#include<stack>
#include<cstdio>
#include<map>
#include<set>
#include<string>
#include<queue>
using namespace std;
#define inf 0x3f3f3f3f
#define ri register int
typedef long long ll;

inline ll gcd(ll i,ll j){
	return j==0?i:gcd(j,i%j);
}
inline ll lcm(ll i,ll j){
	return i/gcd(i,j)*j;
}
inline void output(int x){
	if(x==0){putchar(48);return;}
	int len=0,dg[20];
	while(x>0){dg[++len]=x%10;x/=10;}
	for(int i=len;i>=1;i--)putchar(dg[i]+48);
}
inline void read(int &x){
    char ch=x=0;
    int f=1;
    while(!isdigit(ch)){
    	ch=getchar();
		if(ch==‘-‘){
			f=-1;
		}	
	}
    while(isdigit(ch))
        x=x*10+ch-‘0‘,ch=getchar();
        x=x*f;
}
const int maxn=2e7+5;
int dis[maxn];
int prm[maxn];
int vis[maxn];
int sum[maxn];
void work(){
	dis[1]=1;
	for(int i=2;i<=2e7;i++){
		if(vis[i]==0){
			prm[++prm[0]]=i;
			dis[i]=2;
		}
		for(int j=1;j<=prm[0]&&i*prm[j]<=2e7;j++){
		//	cout<<i<<" "<<prm[j]<<endl;
			vis[i*prm[j]]=1;
			if(i%prm[j]==0){
				if(i%((ll)prm[j]*prm[j])==0){//说明i*prm[j]可以分解出三个相同的质因数 
					dis[i*prm[j]]=0;
				}
				else{
					dis[i*prm[j]]=dis[i/prm[j]];
				}
				break;
			}
			dis[i*prm[j]]=dis[i]*dis[prm[j]];
		}
	}
	sum[1]=1;
	for(int i=2;i<=2e7;i++){
		sum[i]+=sum[i-1]+dis[i];
	}
}
int main(){
	work();
	int t;
	read(t);
	while(t--){
		int n;read(n);
		output(sum[n]);
		printf("\n");
	}
	return 0;
}

 

ACM-ICPC 2018 南京赛区网络预赛 J.sum(欧拉筛)

原文:https://www.cnblogs.com/Zhi-71/p/10549834.html

(0)
(0)
   
举报
评论 一句话评论(0
关于我们 - 联系我们 - 留言反馈 - 联系我们:wmxa8@hotmail.com
© 2014 bubuko.com 版权所有
打开技术之扣,分享程序人生!