P3708 koishi的数学题

题目描述

Koishi在Flandre的指导下成为了一名数学大师,她想了一道简单的数学题。

输入一个整数n,设P3708 koishi的数学题,你需要输出f(1),f(2)...f(n)。

按照套路,Koishi假装自己并不会做这道题,就来求你帮忙辣。

输入格式

一个正整数n。

输出格式

一行用空格分隔的n个整数f(1),f(2)...f(n)。

输入输出样例

输入 #1
10
输出 #1
9 16 22 25 29 27 29 24 21 13

说明/提示

对于20%的数据,n≤1000。

对于60%的数据,n≤10^5。

对于100%的数据,1≤n≤10^6。

思路

代码

#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
using namespace std;

const int N=1000010;

bool flag[N];
long long f[N],ans[N];
int tot,n,prim[N],t[N];

void init() {
	f[1]=1;
	for(int i=2; i<=n; i++) {
		if (!flag[i]) {
			prim[++tot]=i;
			f[i]=i+1;
			t[i]=i;
		}
		for(int j=1; j<=tot; j++) {
			int k=prim[j]*i;
			if(k>n)
				break;
			flag[k]=1;
			if(i%prim[j]==0) {
				t[k]=t[i]*prim[j];
				if(k==t[k])
					for(int l=1; l<=k; l*=prim[j])
						f[k]+=l;
				else
					f[k]=f[t[k]]*f[k/t[k]];
				break;
			}
			t[k]=prim[j];
			f[k]=f[prim[j]]*f[i];
		}
	}
}

int main() {
	scanf("%d",&n);
	init();
	ans[1]=n-1;
	for(int i=2; i<=n; i++)
		ans[i]=ans[i-1]+n-f[i];
	for(int i=1; i<=n; i++)
		printf("%lld ",ans[i]);
	printf("\n");
	return 0;
}

 

上一篇:prim算法【最小生成树1】


下一篇:最小生成树:Prim算法和Kruskal算法