• [CQOI2015]选数


    题目链接:Click here

    Solution:

    先把式子列出来

    [sum_{i_1=L} ^{H}sum_{i_2=L}^H dotssum_{i_n=L}^H [gcd(i_{j=1}^n)=k]\ ]

    接下来就是莫反套路了

    [sum_{i_1=lfloor{L-1 over k} floor} ^{lfloor{Hover k} floor}sum_{i_2=lfloor{L-1 over k} floor}^{lfloor{Hover k} floor} dotssum_{i_n=lfloor{L-1 over k} floor}^{lfloor{Hover k} floor} [gcd(i_{j=1}^n)=1]\ sum_{d=1}^{lfloor{Hover k} floor}mu(d)sum_{i_1=lfloor{L-1 over kd} floor} ^{lfloor{Hover kd} floor}sum_{i_2=lfloor{L-1 over kd} floor}^{lfloor{Hover kd} floor} dotssum_{i_n=lfloor{L-1 over kd} floor}^{lfloor{Hover kd} floor} \ ]

    把后面的东西提出来,等于((lfloor{Hover kd} floor-lfloor{L-1 over kd} floor)^n),即

    [sum_{d=1}^{lfloor{Hover k} floor}mu(d)(lfloor{Hover kd} floor-lfloor{L-1 over kd} floor)^n ]

    杜教筛筛(mu)是基本操作,在数论分块即可

    Code:

    #include<bits/stdc++.h>
    #define int long long
    using namespace std;
    const int N=2e6+11;
    const int mod=1e9+7;
    const int inf=1919191919;
    bool vis[N];
    int L,R,n,k,cnt;
    int ans,p[N],u[N];
    unordered_map<int,int> vu;
    int read(){
    	int x=0,f=1;char ch=getchar();
    	while(!isdigit(ch)){if(ch=='-')f=-f;ch=getchar();}
    	while(isdigit(ch)){x=x*10+ch-48;ch=getchar();}
    	return x*f;
    }
    int qpow(int a,int b){
        int re=1;
        while(b){
            if(b&1) re=re*a%mod;
            b>>=1;a=a*a%mod;
        }return re%mod;
    }
    void prepare(){
        u[1]=1;
        for(int i=2;i<N;i++){
            if(!vis[i]) p[++cnt]=i,u[i]=-1;
            for(int j=1;j<=cnt&&i*p[j]<N;j++){
                vis[i*p[j]]=1;
                if(i%p[j]==0) break;
                u[i*p[j]]=-u[i];
            }
        }
        for(int i=1;i<N;i++) u[i]+=u[i-1];
    }
    int getS(int x){
        if(x<N) return u[x];
        if(vu[x]) return vu[x];
        int re=1;
        for(int i=2,j;i<=x;i=j+1){
            j=x/(x/i);
            re-=getS(x/i)*(j-i+1)%mod;
            re=(re+mod)%mod;
        }return vu[x]=re;
    }
    signed main(){
        prepare();
        n=read(),k=read(),L=read(),R=read();
        --L;L/=k;R/=k;
        for(int i=1,j;i<=R;i=j+1){
            j=min(L/i?L/(L/i):inf,R/(R/i));
            int v=(getS(j)-getS(i-1))%mod;
            int tmp=(R/i-L/i);tmp=qpow(tmp,n);
            ans+=tmp*v%mod;ans=(ans+mod)%mod;
        }
        printf("%lld
    ",ans);
        return 0;
    }
    
  • 相关阅读:
    springboot基本注解
    Mybatis之简单注解
    java再次学习
    在线html编辑器
    分享
    cyberduck的SSH登录
    ie67的冷知识
    css特效
    小程序分享
    css特效博客
  • 原文地址:https://www.cnblogs.com/NLDQY/p/12069487.html
Copyright © 2020-2023  润新知