[SDOI2015]约数个数和

题链

SOL:不存在的。

#include<bits/stdc++.h>
#define LL long long
#define N 50017
#define sight(c) ('0'<=c&&c<='9')
using namespace std;
LL Sum,smu[N],mu[N],pim[N],tot,dd[N],sd[N],sum[N];
int T,n,m;
inline void read(int &x){
    static char c;
    for (c=getchar();!sight(c);c=getchar());
    for (x=0;sight(c);c=getchar())x=x*10+c-48;
}
void write(LL x){if (x<10) {putchar('0'+x); return;} write(x/10); putchar('0'+x%10);}
inline void writeln(LL x){ if (x<0) putchar('-'),x*=-1; write(x); putchar('\n'); }
inline void writel(LL x){ if (x<0) putchar('-'),x*=-1; write(x); putchar(' '); }
bool usd[N];
void init() {
    smu[1]=1; sum[1]=1;
    for (int i=2;i<N;i++) {
        if (!usd[i]) pim[++tot]=i,mu[i]=-1,sd[i]=2,dd[i]=1;
        for (int j=1;j<=tot&&pim[j]*i<N;j++) {
            usd[i*pim[j]]=1;
            if (i%pim[j]==0) {
                mu[i*pim[j]]=0; 
                sd[i*pim[j]]=sd[i]/(dd[i]+1)*(dd[i]+2);
                dd[i*pim[j]]=dd[i]+1; 
                break;}
            mu[i*pim[j]]=-mu[i]; sd[i*pim[j]]=sd[i]<<1; dd[i*pim[j]]=1;
        }
        smu[i]=smu[i-1]+mu[i]; sum[i]=sum[i-1]+sd[i];
    }
}
int main() {
    init();
    read(T);
    while (T--) {
        read(n); read(m); Sum=0;
        if (n>m) swap(n,m); 
        for (int i=1,last;i<=n;i=last+1) {
            last=min(n/(n/i),m/(m/i));
            Sum+=(smu[last]-smu[i-1])*sum[n/i]*sum[m/i];
        }
        writeln(Sum);
    } return 0;
}

 

posted @ 2018-03-03 20:54  泪寒之雪  阅读(139)  评论(0编辑  收藏  举报