【JZOJ4919】【NOIP2017提高组模拟12.10】神炎皇

题目描述

神炎皇乌利亚很喜欢数对,他想找到神奇的数对。
对于一个整数对(a,b),若满足a+b<=n且a+b是ab的因子,则成为神奇的数对。请问这样的数对共有多少呢?

数据范围

对于100%的数据n<=100000000000000。

=w=

引理一

两个互质的数之差与这两个数互质。
证明:
证明依赖于欧几里得算法的 gcd(a,b)=gcd(b,ab)
1.设 a>b,r=(a,b) ,则有 r|a,r|b ,表示成 a=ar,b=br
则有 (b,ab)=(br,(ab)r) ,显然 (b,ab) 也有 r 这个公约数。

2.设r=(a,b),则有 r|a,r|b ,表示成 a=ar,b=br
则有 (a+b,a)=((a+b)r,ar) ,显然 (a+b,a) 也有 r 这个公约数。

综合1,2,(a,b)的公约数也是 (b,ab) 的公约数,所以 gcd(a,b)=gcd(b,ab)
回到原命题, gcd(p,q)=1gcd(q,pq)=1

引理二

两个互质的数的和与积互质。
证明:
gcd(p,q)=1
根据引理一,则有
gcd(p+q,q)=gcd(q,p)=1,gcd(p+q,p)=gcd(p,q)=1
也就是说 (p+q) p q都互质,必然就和 pq 互质。

正文

(a,b) 合法,那么存在 (a+b)|ab
d=gcd(a,b) ,并且 ad=a,bd=b
那么就有 (a+b)d|abd2 ,即 (a+b)|abd


根据引理二,又 a b 互质,则 (a+b)|d
题设有 a+b<=n ,那么 (a+b)d<=n


(a+b)|d d 至少为(a+b)
(a+b)d<=n ,那么 (a+b)<=n


不妨枚举 i=(a+b) ,这样 d 就只能取n/i个了,每隔 i 个有一个d|i
所以合法的 d 就有n/i2个。
再来考虑符合 (a+b)=i 的个数,由引理一:
如果存在一个 gcd(c,i)=1 ,那么必然存在一个 gcd(c,ic)=1
于是乎, (a+b)=i 的个数即为 φ(i) ,可用线性筛法预处理。


综上, ans=ni=2ni2φ(i)
时间复杂度为 O(n)

代码

#include<iostream>
#include<stdio.h>
#include<string.h>
#include<math.h>
#include<algorithm>
#define ll long long
using namespace std;
const char* fin="uria.in";
const char* fout="uria.out";
const int inf=0x7fffffff;
const int maxn=10000007;
ll n,i,j,k,nq;
ll ans;
ll p[maxn],phi[maxn];
bool bz[maxn];
int main(){
    freopen(fin,"r",stdin);
    freopen(fout,"w",stdout);
    scanf("%lld",&n);
    nq=(ll)sqrt(n);
    for (i=2;i<=nq;i++){
        if (bz[i]==false){
            phi[i]=i-1;
            p[++p[0]]=i;
            ans+=phi[i]*(n/i/i);
        }
        for (j=1;j<=p[0];j++){
            k=i*p[j];
            if (k>nq) break ;
            if (i%p[j]==0) phi[k]=phi[i]*p[j];
            else  phi[k]=phi[i]*(p[j]-1);
            bz[k]=true;
            ans+=phi[k]*(n/k/k);
            if (i%p[j]==0) break;
        }
    }
    printf("%lld\n",ans);
    return 0;
}

=o=

线性筛法求欧拉函数

首先有通式,
φ(p1k1p2k2...pnkn)=(p11)p1k11(p21)p2k21...(pn1)pnkn1
显然用线筛通过简单转移可以得到。

~

一开始我也考虑分析这个东西,
(a,b) 合法就有 (a+b)|abd
然后就不会了。
并没有考虑到 gcd(a+b,ab)=1 这个性质。
日后这种数论计数问题,先从合法的开始分析。
如果涉及倍数关系,可以考虑排除一些不作贡献的干扰项。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

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

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

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值