YY的GCD

传送门

题目描述很清楚,还是先老套路枚举gcd,不过这次你枚举的只能是质数。

\[\sum_{i=1}^n\sum_{j=1}^m\sum_{d=1,d\ is\ prime}^n[gcd(i,j)=d] \]

这个式子我们很熟悉。直接d除进去然后套莫比乌斯函数的性质:

\[\sum_{d=1,d\ is\ prime}^n \sum_{p=1}^{\frac{n}{d}}\mu(p)\left\lfloor\frac{n}{dp}\right\rfloor\left\lfloor\frac{m}{dp}\right\rfloor \]

这个式子的形式好像非常熟悉……?后面那一大串在d固定的时候,是可以整除分块\(O(\sqrt{n})\)计算的。然后前面的那一层循环枚举质数,其实只是对你里面莫比乌斯函数的值有影响,这个也可以用前缀和维护的。

然后在前面随便枚举的时候,我们是使用过类似埃氏筛法的方法统计的。这次也一样,直接用所有筛出来的素数更新其倍数的莫比乌斯函数前缀和即可,之后对于每组询问整除分块做。

这题不知道为啥……我和别人都是一个算法但是跑的死慢……不开O2过不去……

// luogu-judger-enable-o2
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
#include<cmath>
#include<set>
#include<vector>
#include<map>
#include<queue>
#define rep(i,a,n) for(int i = a;i <= n;i++)
#define per(i,n,a) for(int i = n;i >= a;i--)
#define enter putchar('\n')
#define fr friend inline
#define y1 poj
#define mp make_pair
#define pr pair<int,int>
#define fi first
#define sc second
#define pb push_back
#define I puts("bug")

using namespace std;
typedef long long ll;
const int M = 10000005;
const int INF = 1000000009;
const double eps = 1e-7;
const double pi = acos(-1);
const ll mod = 1e9+7;

ll read()
{
    ll ans = 0,op = 1;char ch = getchar();
    while(ch < '0' || ch > '9') {if(ch == '-') op = -1;ch = getchar();}
    while(ch >= '0' && ch <= '9') ans = ans * 10 + ch - '0',ch = getchar();
    return ans * op;
}

ll T,n,m,p[M],tot,mu[M],sum[M],g[M];
bool np[M];

void euler()
{
   np[1] = 1,mu[1] = 1;
   rep(i,2,M-2)
   {
      if(!np[i]) p[++tot] = i,mu[i] = -1;
      for(int j = 1;i * p[j] <= M-2;j++)
      {
     np[i * p[j]] = 1;
     if(!(i % p[j])) break;
     mu[i * p[j]] = -mu[i]; 
      }
   }
   rep(j,1,tot)
      for(int i = 1;i * p[j] <= M-2;i++) g[i * p[j]] += mu[i];
   rep(i,1,M-2) sum[i] = sum[i-1] + g[i];
}

int main()
{
   euler();
   T = read();
   while(T--)
   {
      n = read(),m = read();
      ll k = min(n,m),ans = 0;
      for(int i = 1,j;i <= k;i = j+1)
      {
     j = min(n / (n / i),m / (m / i));
     ans += (ll)(n / i) * (m / i) * (ll)(sum[j] - sum[i-1]);
      }
      printf("%lld\n",ans);
   }
   return 0;
}

posted @ 2018-12-15 01:15  CaptainLi  阅读(129)  评论(0编辑  收藏  举报