[题解] BZOJ 2693 jzptab

BZOJ 2693 jzptab

Solution

题目要求:

i = 1 n j = 1 m L C M ( i , j )

多组询问

BZOJ 2154 Crash的数字表格的唯一区别就是加了多组询问
但是在Crash的数字表格中,已经将询问优化到 n
所以直接control+c control+v即可
总时间复杂度为 O ( n + T n )

代码如下:

#include <bits/stdc++.h>
using namespace std;
const int N = 10000005;
const int mod = 100000009;
int pri[N],tot,mu[N],n,m,t;
long long f[N];
long long s[N];
bool mark[N];
void get() {
    mu[1]=1;
    f[1]=1;
    for(register int i=2;i<=10000000;++i) {
        if(!mark[i]) {
            pri[++tot]=i;
            f[i]=1-i;
            mu[i]=-1;
        }
        for(register int j=1;j<=tot && pri[j]*i<=10000000;++j) {
            mark[i*pri[j]]=1;
            if(i%pri[j]==0) { 
                f[i*pri[j]]=f[i];
                break;
            }
            f[i*pri[j]]=f[i]*f[pri[j]]%mod;
            mu[i*pri[j]]=-mu[i];
        }
    }
    for(register int i=1;i<=10000000;++i) {
        f[i]=((f[i]*i)%mod+f[i-1])%mod;
        s[i]=(s[i-1]+i)%mod;
    }
}
void work() {
    scanf("%d%d",&n,&m);
    if(n>m) swap(n,m);
    int pos=0,ans=0;
    for(int i=1;i<=n;i=pos+1) {
        pos=min(n/(n/i),m/(m/i));
        ans=(ans+(f[pos]-f[i-1]+mod)%mod*s[n/i]%mod*s[m/i]%mod)%mod;
    }
    printf("%d\n",(ans+mod)%mod);
}
int main() {
    get();
    scanf("%d",&t);
    while(t--) work();
    return 0;
}

猜你喜欢

转载自blog.csdn.net/force_chl/article/details/80638408