[BZOJ4805]欧拉函数求和

题目大意:
  对于给定的$n(n\leq2\times10^9)$,求$\sum_{i=1}^n\varphi(i)$。

思路:
  设$S(n)=\sum_{i=1}^n\varphi(i)$。
  因为$\sum_{d|n}\varphi(d)=n$,$S(n)=\sum_{i=1}^n(i-\sum_{d|i,d<i}\varphi(d))=\frac{n(n+1)}2-\sum_{i=2}^nS(\lfloor\frac ni\rfloor)$。
  

 1 #include<cmath>
 2 #include<cstdio>
 3 #include<cctype>
 4 #include<hash_map>
 5 typedef long long int64;
 6 inline int getint() {
 7     register char ch;
 8     while(!isdigit(ch=getchar()));
 9     register int x=ch^'0';
10     while(isdigit(ch=getchar())) x=(((x<<2)+x)<<1)+(ch^'0');
11     return x;
12 }
13 const int N=1587402,M=120256;
14 bool vis[N];
15 int lim,phi[N],p[M];
16 int64 sum[N];
17 __gnu_cxx::hash_map<int,int64> map;
18 inline void sieve() {
19     sum[1]=phi[1]=1;
20     for(register int i=2;i<=lim;i++) {
21         if(!vis[i]) {
22             p[++p[0]]=i;
23             phi[i]=i-1;
24         }
25         for(register int j=1;j<=p[0]&&i*p[j]<=lim;j++) {
26             vis[i*p[j]]=true;
27             if(i%p[j]==0) {
28                 phi[i*p[j]]=phi[i]*p[j];
29                 break;
30             }
31             phi[i*p[j]]=phi[i]*phi[p[j]];
32         }
33         sum[i]=sum[i-1]+phi[i];
34     }
35 }
36 inline int64 calc(const int &n) {
37     if(n<=lim) return sum[n];
38     if(map.count(n)) return map[n];
39     int64 ans=(int64)n*(n+1)/2;
40     for(int l=2,r;l<=n;l=r+1) {
41         r=n/(n/l);
42         ans-=calc(n/l)*(r-l+1);
43     }
44     return map[n]=ans;
45 }
46 int main() {
47     const int n=getint();
48     lim=pow(n,2./3);
49     sieve();
50     printf("%lld\n",calc(n));
51     return 0;
52 }

 

线性筛预处理$S$的前$n^{\frac23}$项,剩下的数论分块计算,用哈希表保存已经算过的值,记忆化搜索即可。时间复杂度$O(n^{\frac23})$。

转载于:https://www.cnblogs.com/skylee03/p/8473158.html

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
BZOJ 2908 题目是一个数据下载任务。这个任务要求下载指定的数据文件,并统计文件中小于等于给定整数的数字个数。 为了完成这个任务,首先需要选择一个合适的网址来下载文件。我们可以使用一个网络爬虫库,如Python中的Requests库,来帮助我们完成文件下载的操作。 首先,我们需要使用Requests库中的get()方法来访问目标网址,并将目标文件下载到我们的本地计算机中。可以使用以下代码实现文件下载: ```python import requests url = '目标文件的网址' response = requests.get(url) with open('本地保存文件的路径', 'wb') as file: file.write(response.content) ``` 下载完成后,我们可以使用Python内置的open()函数打开已下载的文件,并按行读取文件内容。可以使用以下代码实现文件内容读取: ```python count = 0 with open('本地保存文件的路径', 'r') as file: for line in file: # 在这里实现对每一行数据的判断 # 如果小于等于给定整数,count 加 1 # 否则,不进行任何操作 ``` 在每一行的处理过程中,我们可以使用split()方法将一行数据分割成多个字符串,并使用int()函数将其转换为整数。然后,我们可以将该整数与给定整数进行比较,以判断是否小于等于给定整数。 最后,我们可以将统计结果打印出来,以满足题目的要求。 综上所述,以上是关于解决 BZOJ 2908 数据下载任务的简要步骤和代码实现。 希望对您有所帮助。

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值