题目描述

给定整数N,求1<=x,y<=N且Gcd(x,y)为素数的数对(x,y)有多少对.

输入输出格式

输入格式:

一个整数N

输出格式:

答案

输入样例#1:

4

输出样例#1:

4

说明

对于样例(2,2),(2,4),(3,3),(4,2)

1<=N<=10^7

上午用这道题考试(虽然略有区别不过差不多)qwq

用欧拉函数乱推。。。

code:(ac代码)

#include<cstdio>
#define LL long long const int N=10000010;
int n,cnt;
int pri[N],phi[N];
LL ans;
LL qphi[N];
bool vis[N]; void init() {
vis[1]=phi[1]=1;
for(int i=2;i<=n;i++) {
if(!vis[i]) pri[++cnt]=i,phi[i]=i-1;
for(int j=1;j<=cnt && pri[j]*i<=n;j++) {
vis[pri[j]*i]=1;
if(!(i%pri[j])) {phi[i*pri[j]]=phi[i]*pri[j];break;}
else phi[i*pri[j]]=phi[i]*phi[pri[j]];
}
}
for(int i=1;i<=n;i++) qphi[i]=qphi[i-1]+phi[i];//前缀和
} int main() {
scanf("%d",&n);
init();
for(int i=1;i<=cnt;i++)
ans+=(qphi[(n-n%pri[i])/pri[i]]<<1)-1;
//稍微解释:因为每次枚举中有一种情况为(pi,pi) (pi为范围内第i个素数) 应被算作一种其余的都应乘2
//也可以刚开始按乘2算出来最后减去素数个数
printf("%lld",ans);
return 0;
}

code:(考试原代码)

PS:由于考题与本题略有不同不能过本题而且懒得改了,此处仅为记录原考题(即(2,4)与(4,2)视作一种情况)的代码

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<ctime>
#define LL long long
using namespace std; const int N=10000010;
int n,cnt;
LL ans;
int pri[N/10],phi[N];
LL qphi[N];
bool vis[N]; int gcd(int a,int b) {//原始暴力算法(n^2)
return !b?a:gcd(b,a%b);
} void init() {//欧拉筛
vis[1]=1;phi[1]=1;
for(register int i=2;i<=n;i++) {
if(!vis[i]) pri[++cnt]=i,phi[i]=i-1;
for(register int j=1;j<=cnt && pri[j]*i<=n;j++) {
vis[pri[j]*i]=1;
if(i%pri[j]==0) {
phi[i*pri[j]]=phi[i]*pri[j];
break;
}
else phi[i*pri[j]]=phi[i]*phi[pri[j]];
}
}
for(int i=1;i<=n;i++) qphi[i]=qphi[i-1]+phi[i];
} int get(int x) {//高级暴力的二分
if((x<<1)>n) return 0;
int l=1,r=cnt;
while(l<r) {
int mid=(l+r+1)>>1;
if(pri[mid]*x<=n) l=mid;
else r=mid-1;
}
return l;
} int main() {
// freopen("gcd.in","r",stdin);
// freopen("gcd.out","w",stdout);
scanf("%d",&n);
// int be=clock();
init();
// for(register int i=1;i<=n;i++) {//比较快的暴力算法(nlogn)。。
// int x=get(i);
// ans+=x*phi[i];
// }
// printf("%lld",ans);
// ans=0;cout<<endl;
for(register int i=1;i<=cnt;i++) {//能过的~~暴力~~算法(n)
int x=(n-n%pri[i]);
ans+=qphi[x/pri[i]];
}
// cout<<cnt<<endl;
printf("%lld",ans);
// int ed=clock();
// cout<<endl<<ed-be;
return 0;
}

最新文章

  1. (原)android的alertdialog中加入edittext但是不弹出软键盘等问题的解决与原因
  2. oracle高阶知识点
  3. django笔记-模型数据模板呈现过程记录(多对多关系)
  4. Aho-Corasick算法、多模正则匹配、Snort入门学习
  5. dedecms的title怎么优化?
  6. Google面试题:计算从1到n的正数中1出现的次数
  7. DTCMS自定义标签,获取所有栏目以及获得二级子栏目导航
  8. TFS上使用Beyond Compare来比较源码
  9. JavaScript绑定事件的方法[3种]
  10. 极客君教你破解隔壁妹子的wifi密码,成功率高达90%
  11. python库pandas简介
  12. SPP-Net理解
  13. 读书笔记二 How Does the Internet work?
  14. linq之group by 的使用
  15. 硬盘性能测试工具fio
  16. 使用flexible适配移动端h5页面
  17. MySQL递归查询树状表的子节点、父节点
  18. Delphi APP 開發入門(十)REST Client 開發
  19. 孤荷凌寒自学python第七十一天开始写Python的第一个爬虫
  20. sed 概述

热门文章

  1. WSDL详解(一)
  2. nyoj256-C小加之级数求和
  3. BZOJ 4712 洪水 (线段树+树剖动态维护DP)
  4. 配置mysql允许远程访问
  5. Problem 7
  6. [LeetCode] 75. 颜色分类(荷兰国旗)
  7. Linux中/etc/init.d
  8. Hadoop Word Count程序
  9. js面向对象编程: js类定义函数时prototype和this差别?
  10. ubuntu14.04无法安装Curl