题解:

莫比乌斯反演

设f[i]=Σgcd(i,j)%z==0

则f[i]=Σgcd(i,j)==zd

成莫比乌斯反演关系

代码:

#include<cstdio>
#include<cmath>
#include<algorithm>
#include<cstring>
using namespace std;
typedef long long ll;
const int N=100005;
ll ans1,ans2;
int x,y,z,tot,T,cnt,miu[N],flag[N],p[N];
void init()
{
    miu[1]=1;
    for (int i=2;i<N;i++)
     {
         if (!flag[i])
          {
              miu[i]=-1;
              p[++tot]=i;
          }
         for (int j=1;j<=tot;j++)
          {
              int k=p[j]*i;
              if (k>=N)break;
              flag[k]=1;
              if (i%p[j]==0)
               {
                   miu[k]=0;
                   break;
               }
              miu[k]-=miu[i];
          }
     }
}
int main()
{
    scanf("%d",&T);
    init();
    while (T--)
     {
         ans1=ans2=0;
         scanf("%d%d%d%d%d",&x,&x,&y,&y,&z);
         if (!z)
          {
             printf("Case %d: 0\n",++cnt);
             continue;
          }
         x/=z;y/=z;
         if (x>y)swap(x,y);
         for (int i=1;i<=x;i++)ans1+=(ll)miu[i]*(x/i)*(y/i);
         for (int i=1;i<=x;i++)ans2+=(ll)miu[i]*(x/i)*(x/i);
         printf("Case %d: %lld\n",++cnt,ans1-ans2/2);
     }
} 

 

posted on 2018-03-07 17:56  宣毅鸣  阅读(96)  评论(0编辑  收藏  举报