莫比乌斯反演+BIT。
因为答案没有排序而调了很久。。。
#include<iostream> #include<cstdio> #include<cstring> #include<algorithm> #define maxn 100000 #define mod 2147483647LL using namespace std; int tt,n,m,miu[maxn+50],prime[maxn/10],top=0,t[maxn+50],f1[maxn+50],f2[maxn+50],ans[maxn],pos=1; bool vis[maxn+50]; struct f_ { int val,id; }f[maxn+50]; struct query { int n,m,a,id; }q[maxn]; bool cmp1(f_ x,f_ y) { return x.val<y.val; } bool cmp2(query x,query y) { return x.a<y.a; } void get_table() { miu[1]=f1[1]=f2[1]=1; for (int i=2;i<=maxn;i++) { if (!vis[i]) { prime[++top]=i; miu[i]=-1;f1[i]=1;f2[i]=i+1; } for (int j=1;j<=top && i*prime[j]<=maxn;j++) { vis[i*prime[j]]=true; if (i%prime[j]) { miu[i*prime[j]]=-miu[i]; f1[i*prime[j]]=(f1[i]*f2[i])&mod;f2[i*prime[j]]=(prime[j]+1)&mod; } else { miu[i*prime[j]]=0; f1[i*prime[j]]=f1[i]&mod;f2[i*prime[j]]=(((f2[i]*prime[j])&mod)+1)&mod; break; } } } for (int i=1;i<=maxn;i++) { f[i].id=i; f[i].val=(f1[i]*f2[i])&mod; } } int lowbit(int x) {return (x&(-x));} void modify(int x,int val) { for (int i=x;i<=maxn;i+=lowbit(i)) { t[i]=(t[i]+val)&mod; if (t[i]<0) t[i]=(t[i]+mod+1)&mod; } } int ask(int x) { int ret=0; for (int i=x;i>=1;i-=lowbit(i)) ret=(ret+t[i])&mod; return ret; } void work(int x) { int l=1,r,ret=0; int n=q[x].n,m=q[x].m; if (n>m) swap(n,m); while (l<=n) { r=min(n/(n/l),m/(m/l)); ret=(ret+((((n/l)*(m/l))&mod)*(ask(r)-ask(l-1)+mod+1))&mod)&mod; l=r+1; } ans[q[x].id]=ret; } int main() { get_table(); scanf("%d",&tt); for (int i=1;i<=tt;i++) { scanf("%d%d%d",&q[i].n,&q[i].m,&q[i].a); q[i].id=i; } sort(f+1,f+maxn+1,cmp1); sort(q+1,q+tt+1,cmp2); for (int i=1;i<=tt;i++) { int j; for (j=pos;j<=maxn;j++) { if (f[j].val>q[i].a) break; for (int k=1;k*f[j].id<=maxn;k++) modify(k*f[j].id,f[j].val*miu[k]); } pos=j; work(i); } for (int i=1;i<=tt;i++) printf("%d\n",ans[i]); return 0; }