day10

Posted on 2017-06-10 10:32  Amphetamine  阅读(114)  评论(2编辑  收藏  举报

今天改题(昨天不是励志把所有题都a了吗)今天是一道day2的数论提,当时听大佬讲了一遍自己又理解了一下,以为懂了,但是到了写程序的时候,才发现还差着好多。

(这就是我和大佬的差距吧)由参考一下标程+自己理解,终于把这道题a了;

f[i*prime[j]]=f[i]*prime[j]*prime[j]-f[t]*prime[j]+f[t];

f[i*prime[j]]=f[i]*(prime[j]-1)*prime[j]+f[i];

首先大佬讲过 f[i]就是i所有约数*约数的phi的和

这两个式子是核心 第一个 t与p[j](以下简称p)互质 (i的所有约数-t的所有约数)*phi[]*p*p+t的所有约数*p*(p-1)*phi[]+t*phi[];

对于f[i*p]=f[i]+f新增 

(i约-t约)*phi[]*p*p=所有新增+部分f[i](所有含p平方约数)

t的所有约数*p*(p-1)*phi[](所有只含p一次方约数)

t*phi[](不含p约数)

 

本人思路不正,欢迎大佬指正

 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<cmath>
 5 using namespace std;
 6 #define M 10000005
 7 #define ll long long
 8 bool flag[M];
 9 int prime[M/3];ll f[M];
10 void getp(){
11     //memset(flag,0,sizeof(flag));
12     int k=0;
13     f[1]=1;
14     for(int i=2;i<=M;i++){
15         if(!flag[i]){
16         prime[++k]=i;
17         f[i]=(ll)i*(i-1)+1;}
18         for(int j=1;j<=k&&i*prime[j]<=M;j++){
19             flag[i*prime[j]]=1;
20             if(i%prime[j]==0){
21                 if(f[i*prime[j]])continue;
22                 int t=i/prime[j];
23                 while(t%prime[j]==0)t/=prime[j];
24                 f[i*prime[j]]=f[i]*prime[j]*prime[j]-f[t]*prime[j]+f[t];
25             }
26             else f[i*prime[j]]=f[i]*(prime[j]-1)*prime[j]+f[i];
27         }
28     }
29 }
30 
31 int main(){
32     freopen("maths.in","r",stdin);
33     freopen("maths.out","w",stdout);
34     getp();
35     //f[1]=1;
36     int t,n;
37     cin>>t;
38     while(t--){
39         cin>>n;
40         cout<<f[n]<<endl;
41     }
42     return 0;
43 }
maths