传送门:
水题(省选难度?)
有点自豪!!!
#include <cstdio> #include <cstring> #include <string> #include <cmath> #include <algorithm> using namespace std; #define ll long long #define re register const int N=5e4+10; const int M=5e4; int pri[N],cnt; ll mu[N],G[N]; bool vis[N]; void read(int &a) { a=0; int d=1; char ch; while(ch=getchar(),ch>'9'||ch<'0') if(ch=='-') d=-1; a=ch^48; while(ch=getchar(),ch>='0'&&ch<='9') a=(a<<3)+(a<<1)+(ch^48); a*=d; } inline void init() { mu[1]=1; for(re int i=2;i<=M;i++) { if(!vis[i]) pri[++cnt]=i,mu[i]=-1; for(re int j=1;j<=cnt&&i*pri[j]<=M;j++) { vis[i*pri[j]]=1; if(i%pri[j]==0) break; mu[i*pri[j]]=-mu[i]; } } for(re int i=1;i<=M;i++) mu[i]+=mu[i-1]; for(re int i=1;i<=M;i++) { ll ans=0; for(int j=1,r;j<=i;j=r+1) { r=i/(i/j); ans+=(r-j+1)*(i/j); } G[i]=ans; } } inline ll solve(int n,int m) { if(n>m) swap(n,m); ll ans=0; for(int l=1,r;l<=n;l=r+1) { r=min(n/(n/l),m/(m/l)); ans+=(mu[r]-mu[l-1])*G[n/l]*G[m/l]; } return ans; } int main() { init(); int T; read(T); while(T--) { int n,m; read(n); read(m); printf("%lld ",solve(n,m)); } return 0; }