这里用的是最近比较流行的EES方法解决的
不了解的可以看下这篇文章:
https://blog.csdn.net/Feynman1999/article/details/82874491
这种方法只要能找出f(pe)f(p^e)f(pe)的表达式,并且当e+1e+1e+1时可以O(1)O(1)O(1)维护,就可以用EES筛法去做
对于本题而言,考虑函数S(n)=∑i=1ngcd(i,n)S(n)=\sum_{i=1}^ngcd(i,n)S(n)=∑i=1n​gcd(i,n),可知若能快速求出其和函数的值记做res,则2∗res−(1+2+3+...+n)2*res-(1+2+3+...+n)2∗res−(1+2+3+...+n)即为ans
如何求res呢?
可知函数S(n)S(n)S(n)是积性函数,实际上S(n)=∑d∣Nφ(Nd)∗dS(n)=\sum_{d|N}\varphi(\frac{N}{d})*dS(n)=∑d∣N​φ(dN​)∗d,可以看到他是欧拉函数和单位函数的狄利克雷卷积。那我们列出S(p)=2p−1S(p)=2p-1S(p)=2p−1,S(pe+1)=p∗S(Pe)+φ(pe+1)S(p^{e+1})=p*S(P^e)+\varphi(p^{e+1})S(pe+1)=p∗S(Pe)+φ(pe+1) ,那只要维护一个欧拉函数即可,φ(p)=p−1,φ(pe+1)=p∗φ(pe)\varphi(p)=p-1,\varphi(p^{e+1})=p*\varphi(p^{e})φ(p)=p−1,φ(pe+1)=p∗φ(pe)
维护p1,p0p^1,p^0p1,p0的前缀即可(看了EES才知道这里前缀是什么意思)
没有特别要注意的地方

代码

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
const int mod=1e9+7;
const int ni6=166666668;
const int ni2=500000004;
ll n,M;
vector<int> pre[2],hou[2],primes,pri_ni;inline int add(const int x, const int v) {return x + v >= mod ? x + v - mod : x + v;
}
inline int dec(const int x, const int v) {return x - v < 0 ? x - v + mod : x - v;
}//这里res是n/枚举的数
int dfs(ll res, int last, ll f){//最大质因子是prime[last-1] 但将1放在外面值显然一样//cout<<n<<" "<<res<<endl;int t=dec((res > M ? hou[1][n/res] : pre[1][res]),pre[1][primes[last]-1]);//cout<<t<<endl;int ret= (ll)t*f%mod;//这里需修改for(int i=last;i<(int) primes.size();++i){int p = primes[i];if((ll)p*p > res) break;ll phi=p-1;ll ftp=(2*p-1);for(ll q=p,nres=res,nf=f*ftp%mod;q*p<=res;q*=p){//nf需修改ret = add(ret,dfs(nres/=p,i+1,nf));//枚举更大的数phi = phi*p%mod;ftp = add(p*ftp%mod,phi);nf = f*ftp%mod;//继续枚举当前素数的指数ret =add(ret,nf);//指数大于1时,记上贡献}}return ret;
}inline int ff(ll x){x%=mod;return x*(x+1)%mod*ni2%mod;
}inline int fff(ll x){x%=mod;return x*(x+1)%mod*(2*x+1)%mod*ni6%mod;
}int solve(ll n){M=sqrt(n);for(int i=0;i<2;++i){pre[i].clear();pre[i].resize(M+1);hou[i].clear();hou[i].resize(M+1);}primes.clear();primes.reserve(M+1);pri_ni.clear();pri_ni.reserve(M+1);for(int i=1;i<=M;++i){pre[0][i]=i-1;hou[0][i]=(n/i-1)%mod;pre[1][i]=dec(ff(i),1);;hou[1][i]=dec(ff(n/i),1);}for(int p=2;p<=M;++p){if(pre[0][p]==pre[0][p-1]) continue;primes.push_back(p);const ll q=(ll)p*p,m=n/p;const int pnt0=pre[0][p-1],pnt1=pre[1][p-1];const int mid=M/p;const int End=min((ll)M,n/q);for(int i=1;i<=mid;++i){hou[0][i]=dec(hou[0][i],dec(hou[0][i*p],pnt0));hou[1][i]=dec(hou[1][i],dec(hou[1][i*p],pnt1)*(ll)p%mod);//hou[2][i]=dec(hou[2][i],dec(hou[2][i*p],pnt2)*q%mod);}for(int i=mid+1;i<=End;++i){hou[0][i]=dec(hou[0][i],dec(pre[0][m/i],pnt0));hou[1][i]=dec(hou[1][i],dec(pre[1][m/i],pnt1)*(ll)p%mod);//hou[2][i]=dec(hou[2][i],dec(pre[2][m/i],pnt2)*q%mod);}for(int i=M;i>=q;--i){pre[0][i]=dec(pre[0][i],dec(pre[0][i/p],pnt0));pre[1][i]=dec(pre[1][i],dec(pre[1][i/p],pnt1)*(ll)p%mod);//pre[2][i]=dec(pre[2][i],dec(pre[2][i/p],pnt2)*q%mod);}}primes.push_back(M+1);for (int i = 1; i <= M; i++) {pre[1][i] = dec(2*pre[1][i]%mod, pre[0][i]);//2*p-1hou[1][i] = dec(2*hou[1][i]%mod, hou[0][i]);}return n>1 ? add(dfs(n,0,1),1) : 1;
}int main()
{//freopen("in.txt","r",stdin);ios::sync_with_stdio(false);cin>>n;cout<<((2LL*solve(n)-ff(n))%mod+mod)%mod<<endl;return 0;
}

另外附上杜教筛的代码:

#include<bits/stdc++.h>
#define pb push_back
#define mp make_pair
#define bit(a,b) ((a>>b)&1) //from 0
#define all(x) (x).begin(),(x).end()
const int ni2=500000004;
using namespace std;
typedef long long ll;
int debug_num=0;const int mod=1e9+7;
const int maxn=1e7+10;
bool valid[maxn];
int ans[maxn/10];
ll phi[maxn];
const int maxm=(1LL<<37)/maxn;
ll help1[maxm];
bool vis[maxm];
ll tot,up,m;inline ll add(const ll x, const ll v) {//return x + v >= mod ? x + v - mod : x + v;return (x+v)%mod;
}inline ll dec(const ll x, const ll v) {//return x - v < 0 ? x - v + mod : x - v;return (x-v)%mod;
}void get_prime(int n)
{memset(valid,true,sizeof(valid));tot=0;phi[1]=1;for(int i=2;i<=n;++i){if(valid[i]){ans[++tot]=i;phi[i]=i-1;}for(int j=1;j<=tot && ans[j]*i<=n;++j){int tp=ans[j]*i;valid[tp]=false;if(i%ans[j]==0){phi[tp]=phi[i]*ans[j];break;}else{phi[tp]=phi[i]*(ans[j]-1);}}}for(int i=1;i<=n;++i){phi[i]=add(phi[i],phi[i-1]);}
}ll get_phi(ll n)
{return (n<=up) ? phi[n] : help1[m/n] ;
}inline  ff(ll x){x%=mod;return x*(x+1)%mod*ni2%mod;
}void solve1(ll n)
{int t;if(n<=up || vis[t=m/n]) return ;vis[t]=true;help1[t]=ff(n);for(ll l=2,r;l<=n;l=r+1){r=n/(n/l);solve1(n/r);help1[t]=dec(help1[t]%mod,(r-l+1)%mod*get_phi(n/r)%mod);}
}ll solve2(ll n)
{ll ans=0;for(ll l=1,r;l<=n;l=r+1){r=n/(n/l);ll tp=n/r;if(tp<=up){ans=add(ans,(ff(r)-ff(l-1))*phi[tp]%mod);}else{ans=add(ans,(ff(r)-ff(l-1))*help1[m/tp]%mod);}}return ans;
}int main()
{//freopen("in.txt","r",stdin);up=maxn-10;get_prime(up);//cout<<clock()<<endl;ll n;cin>>n;m=n;if(m>up){memset(vis,false,sizeof(vis));solve1(n);}cout<<((2*solve2(n)%mod-ff(n))%mod+mod)%mod<<endl;return 0;
}

51nod1237(EES解法,省空间)相关推荐

  1. 最大公共子序列、子串、可重叠重复子串

    最长公共子序列 寻找两个给定序列的子序列,该子序列在两个序列中以相同的顺序出现,但是不必要是连续的 举例:X=ABCBDAB,Y=BDCABA.序列 BCA是X和Y的一个公共子序列,但不是X和Y的最长 ...

  2. 面向对象的软件工程应用浅研

    来源:http://www.biyelww.com/ [摘要]随着面向对象研究的不断深入,面向对象技术的应用越来越广泛,面向对象的思想被应用到许多不同的领域.在介绍软件工程方法的基础上分析了面向对象的 ...

  3. 华为机试HJ32:密码截取

    作者:翟天保Steven 版权声明:著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处 题目描述: 该题目是一道密码加密题,密码混合在复杂字符串中,是一个对称子字符串,比如12321A ...

  4. 关于CS找实习的不完整经验

    转:http://bbs.byr.cn/#!article/GoAbroad/309095 逛飞版好久了,好像很少看到版里有说关于来美之后找实习的事情.现在大多数14fall的同学应该搞定了出国前的手 ...

  5. 谷歌、苹果、亚马逊等大厂技术面试真题

    技术面试题是许多顶尖科技公司面试的主要内容,其中一些难题会令许多面试者望而却步,但其实这些题是有合理的解决方法的. 7.1 准备事项 多数求职者只是通读一遍问题和解法,囫囵吞枣.这好比试图单凭看问题和 ...

  6. 【Leetcode】面试题 01.08. 零矩阵(Zero Matrix)

    一.题目 编写一种算法,若M × N矩阵中某个元素为0,则将其所在的行与列清零. 二.示例 三.解法 解法-辅助空间 #时间:O(n^2) #空间:O(n^2) class Solution:def ...

  7. Day16-20 - Python语言进阶

    数据结构和算法 算法:解决问题的方法和步骤 评价算法的好坏:渐近时间复杂度和渐近空间复杂度. 渐近时间复杂度的大O标记:  - 常量时间复杂度 - 布隆过滤器 / 哈希存储  - 对数时间复杂度 - ...

  8. 背包问题详解-动态规划

    目录 01背包问题 暴力法 空间优化 背包问题的所有情况 完全背包问题 状态转移方程分析 空间优化 方法二:记录第i件物品的数据k 方法三:转换成01背包 多重背包 方法一:记录第i件物品的数据k 方 ...

  9. 重庆赛区ACM热身赛-8529. Cake

    [问题描述] 小 W 和小 R 同月同日生,今天是他们的生日~ 但是只有一个生日蛋糕,切成了 n 块(每块是角度为 ai 的扇形). 现在他们两人要拿走连续的若干块蛋糕(最终没有蛋糕剩余).他们想知道 ...

最新文章

  1. Sharding-JDBC:垂直拆分怎么做?
  2. Android源码解析(一)动画篇-- Animator属性动画系统
  3. 四.MongoDB 概念解析
  4. 软考-信息系统项目管理师-项目成本管理
  5. python 安装包时出现红字_Python从入门到就业-1.1节:安装Python
  6. Ubuntu连接WiFi
  7. UVa 1626 (输出方案) Brackets sequence
  8. BZOJ 3261: 最大异或和位置-贪心+可持久化01Trie树
  9. 探讨SQL Server 2005的评价函数
  10. ATTCK实战系列二(CS域渗透)
  11. 病毒周报(081208至081214)
  12. 【Java入门基础第6天】六款Java常用的开发工具 废话少说-上号
  13. 普林斯顿微积分读本02第一章--函数的复合、奇偶函数、函数图像
  14. 【5】分享两个小而实用的IP扫描仪
  15. 零基础如何开始学素描?
  16. 关于linux中limits的一些总结
  17. 华为业务:组织架构和产品矩阵
  18. 大学计算机基础网络配置实验报告答案,2008大学计算机基础实验报告参考答案...
  19. 顺序查找 折半查找 二叉排序树
  20. int与Integer、new Integer()

热门文章

  1. WPF 闹钟定时弹出提醒窗口
  2. php本地数据查询,PHP中如何实现首字母数据查询
  3. 源码直通车平台没有中间商赚差价
  4. 【Figma】旋转插件 Rotate Copies 使用方法
  5. 大数据系统架构之降龙八式
  6. windows显示缩略图(重建缩略图)
  7. 判断两条直线(线段)的交点问题
  8. 电动自行车方案 成熟电动自行车代码方案 中颖中颖电动自行车代码方案
  9. Ubuntu 22.04 安装vm-tools
  10. QQ、微信、lol自动发消息工具