BZOJ 2705 Longge的问题 (欧拉函数)
2017-08-11 21:27
302 查看
思路:
根据n的范围我们发现,就算是线性的扫一遍也不行(1e9的复杂度太高了)。所以考虑一种logn或者sqrt(n)的方法;
我们知道这种题多半是不能按照题意直接做,而是要考虑每个gcd对答案的贡献。
考虑n的因子i,以i为gcd的对答案的贡献即为 gcd(某个数,n)==i 的个数乘以i。又因为这道题要算的gcd中有一个是固定值,所以我们可以考虑将之转化为欧拉函数,即,个数为Euler(n/i)。在这个区间里和n/i互质的数,在分别乘以i后,一定就满足 gcd(某个数,n)==i 。
同时,我们注意到每当我们找到n的一个因子i,我们其实同时还获得了n的另一个因子n/i,所以我们就可以通过这个,将复杂度降到sqrt(n)了。
注意,如果n是一个完全平方数,那么记得减去多加的那个因子的一遍贡献。
ps:
对了,这道题由于n太大了,只能每次求euler函数的值,而不能用线性筛o(n)的求。#include<stdio.h> #include <iostream> #include<string.h> #include<math.h> #include<algorithm> #define eps 1e-8 typedef long long int lli; using namespace std; const int maxn = 1e6+10; lli euler(lli n){ lli res = n,x=n;; for(lli i = 2;i*i <= x; i++){ if(x%i==0){ res = res/i * (i-1); while(x%i==0){ x/=i; } } } if(x!=1){ res = res/x*(x-1); } return res; } int main(){ lli p,q; lli a,b; scanf("%lld",&a); lli ans = 0; for(lli i = 1;i*i <= a;i++){ if(a%i == 0){ ans += i*euler(a/i)+ a/i*euler(i); if(i*i==a) ans-= a/i*euler(i); } } printf("%lld\n",ans); return 0; }
相关文章推荐
- [bzoj] 2705 Longge的问题 || 欧拉函数
- [BZOJ 2705] SDOI 2012 Longge的问题 · 欧拉函数
- 【欧拉函数】BZOJ2705(SDOI2012)[Longge的问题]题解
- BZOJ2705 [SDOI2012]Longge的问题 【欧拉函数】
- 【bzoj2705】Longge的问题 欧拉函数
- bzoj 2705: [SDOI2012]Longge的问题 【欧拉函数求GCD】
- bzoj--2705--Longge的问题(欧拉函数)
- 【BZOJ 2705】【SDOI 2012】Longge的问题【欧拉函数】
- BZOJ2705 [SDOI2012]Longge的问题 【欧拉函数】
- 【bzoj2705】【sdoi2012】【longge的问题】【欧拉函数】
- BZOJ.2705.[SDOI2012]Longge的问题(莫比乌斯反演 欧拉函数)
- 【bzoj 2705】Longge的问题(欧拉函数)
- 【bzoj】2705 - [SDOI2012]Longge的问题(欧拉函数)
- [欧拉函数]Bzoj2705 Longge的问题[SDOI2012]
- bzoj 2705: [SDOI2012]Longge的问题 欧拉函数
- 【bzoj2705】[SDOI2012]Longge的问题 欧拉函数
- BZOJ 2705([SDOI2012]Longge的问题-欧拉函数φ(i))
- bzoj2705 [SDOI2012]Longge的问题 欧拉函数
- [BZOJ2705] [SDOI2012] Longge的问题 - 欧拉函数
- bzoj 2705: [SDOI2012]Longge的问题 欧拉函数