triple
Time Limit: 3000MS
Memory Limit: 65536KB
Description
给出一个整数n,表示1,2,...,n。从这n个数中任意选择3个不同的数字x,y,z,问x,y,z的最大公约数等于m的方案有多少种?(注意:(1,2,3),(1,3,2),(2,1,3),(2,3,1),(3,1,2),(3,2,1)属于同一种方案)
Input
第一行输入一个整数T(1 <= T <= 100),表示有T组数据,接下来T行,每行2个整数n, m(1 <= m <= n <= 10^5)
Output
输出一个整数表示答案
Sample Input
15 1
Sample Output
10 题解: qqqq太强啦 ACcode:#include <map> #include <queue> #include <cmath> #include <cstdio> #include <cstring> #include <stdlib.h> #include <iostream> #include <algorithm> #define maxn 1000100 #define ll long long using namespace std; bool vis[maxn]; int mu[maxn],prime[maxn]; void get_M(){ memset(vis,false,sizeof(vis)); mu[1]=1; int tot=0; for(int i=2;i<=maxn;++i){ if(!vis[i]){ prime[tot++]=i; mu[i]=-1; } for(int j=0;j<tot;j++){ if(i*prime[j]>maxn)break; vis[i*prime[j]]=1; if(i%prime[j]==0){ mu[i*prime[j]]=0; break; } else mu[i*prime[j]]=-mu[i]; } } } ll get_F(int i,int n){ ll ret=n/i; if(ret<3)return 0; if(ret==3)return 1; ret=ret*(ret-1)*(ret-2)/6; return ret; } int main(){ int t,n,m; scanf("%d",&t); get_M(); while(t--){ scanf("%d%d",&n,&m); ll ans=0; for(int i=1;i<=n;i++) ans+=(long long)mu[i]*get_F(i*m,n); printf("%lld\n",ans); } return 0; }