【日记】12.26

12.26

莫反

1.BZOJ2154:求lcm

思路:由lcm=i*j/gcd展开,两次分块,总复杂度\(O(n)\)

#include<bits/stdc++.h>
using namespace std;
const int M=1e7+20,P=20101009;
#define LL long long 
int prime[M],cnt,vis[M],mu[M];
void get(int n){
    mu[1]=1;
    for(int i=2;i<=n;i++){
        if(!vis[i])
            prime[++cnt]=i,mu[i]=-1;
        for(int j=1;j<=cnt&&prime[j]*i<=n;j++){
            vis[i*prime[j]]=1;
            if(i%prime[j]==0)
                break;
            mu[i*prime[j]]=-mu[i];
        }
    }
    for(int i=1;i<=n;++i)
        mu[i]=1LL*mu[i]*i*i%P;
    for(int i=1;i<=n;++i)
        mu[i]=(mu[i]+mu[i-1])%P;
}
struct Task{
    int n,m;
    void init(){
        scanf("%d%d",&n,&m);
        get(min(n,m));
    }
    inline LL quad(int n){
        return 1LL*(n+1)*n/2%P;
    }
    inline LL cald(int k,int n,int m){
        LL ans=0;
        for(int l=1,r;l<=k;l=r+1)
            r=min(n/l?min(k,n/(n/l)):k,m/l?min(k,m/(m/l)):k),ans=(ans+1LL*(mu[r]-mu[l-1]+P)%P*quad(n/l)%P*quad(m/l)%P)%P;
        return ans;
    }
    inline LL cald2(int k,int n,int m){
        LL ans=0;
        for(int l=1,r;l<=k;l=r+1)
            r=min(n/l?min(k,n/(n/l)):k,m/l?min(k,m/(m/l)):k),ans=(ans+1LL*(quad(r)-quad(l-1)+P)%P*cald(min(n/l,m/l),n/l,m/l)%P)%P;
        return ans;
    }
    void run(){
        init();
        printf("%lld\n",cald2(min(n,m),n,m));
    }
}t;
int main(){
    t.run();
    return 0;
}

2.BZOJ2693:

#include<bits/stdc++.h>
using namespace std;
const int M=1e7+20,P=1e8+9;
#define LL long long 
int prime[M],cnt,vis[M],mu[M],f[M];
void get(int n){
    mu[1]=f[1]=1;
    for(int i=2;i<=n;i++){
        if(!vis[i])
            prime[++cnt]=i,mu[i]=-1,f[i]=(1-i+P)%P;
        for(int j=1;j<=cnt&&prime[j]*i<=n;j++){
            vis[i*prime[j]]=1;
            if(i%prime[j]==0){
                f[i*prime[j]]=f[i];
                break;
            }
            mu[i*prime[j]]=-mu[i],f[i*prime[j]]=1LL*f[i]*f[prime[j]]%P;
        }
    }
    for(int i=1;i<=n;++i)
        f[i]=1LL*f[i]*i%P;
    for(int i=1;i<=n;++i)
        f[i]=(f[i]+f[i-1])%P;
}
struct Task{
    int n,m;
    void init(){
        scanf("%d%d",&n,&m);
    }
    inline LL quad(int n){
        return 1LL*(n+1)*n/2%P;
    }
    inline LL cald(int k,int n,int m){
        LL ans=0;
        for(int l=1,r;l<=k;l=r+1)
            r=min(n/l?min(k,n/(n/l)):k,m/l?min(k,m/(m/l)):k),ans=(ans+1LL*(f[r]-f[l-1]+P)%P*quad(n/l)%P*quad(m/l)%P)%P;
        return ans;
    }
    void run(){
        init();
        printf("%lld\n",cald(min(n,m),n,m));
    }
}t;
int main(){
    get(1e7);
    int T;
    scanf("%d",&T);
    for(int i=1;i<=T;++i)
        t.run();
    return 0;
}

猜你喜欢

转载自www.cnblogs.com/diorvh/p/12104045.html