您的位置:首页 > 其它

keep on coding 8.26-3

2016-08-27 21:09 218 查看
3.
【问题描述】
数学题。
函数求值:【输入格式】第一行一个整数 T,表示有 T 个询问。接下来 T 行,每行第一个数 n。
【输出格式】
T 行,每行表示第 i 个询问中 F(n)的值
【样例输入 1】
5 1 2 3 4 5
【样例输出 1】
1 3 7
11
21

解决本题基于三个定理:
①当a为质数时 f(a)=a*(a-1)+1;
②当a为质数时 f(a^2)=f(a)*a*a-a+1,更高次方推理类似
③当gcd(a,b)==1时 f(a*b)=f(a)*f(b)
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<cmath>
#define For(i,j,k) for(int i=j;i<=(k);i++)
using namespace std;
const int maxn=10001000;
typedef long long LL;
int zhishu[maxn];
int s[maxn];
LL f[maxn];
void getzhishu(){
For(i,2,maxn-1) zhishu[i]=1;
For(i,2,maxn-1){
if(zhishu[i]){
for(int j=i<<1;j<maxn;j+=i) zhishu[j]=0;
}
}
}
void solve(){
for(LL i=1;i<maxn;i++) f[i]=1LL;
for(LL i=2;i<maxn-1000;i++){
if(zhishu[i]){
s[i]=i;
f[i]=(LL)(i-1)*i+1;
for(LL j=i,k=j*i;j<maxn && k<maxn;j=k,k=j*i){
f[k]=(f[j]*i*i)-i+1;
s[k]=i;
}
}
if(s[i]){
for(LL j=2;j*i<maxn;j++){
if(j%s[i]){
f[j*i]=f[i]*f[j];
}
}
}
}
}
int main(){
getzhishu();
solve();
LL T,n;
scanf("%lld",&T);
while(T--){
scanf("%lld",&n);
printf("%lld\n",f
);
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  博客 递推