• [CQOI2015][bzoj3930] 选数 [杜教筛+莫比乌斯反演]


    题面:

    传送门

    思路:

    首先我们把区间缩小到$left[lfloorfrac{L-1}{K} floor,lfloorfrac{R}{K} floor ight]$

    这道题的最特殊的点在于,他的gcd不是两个数的而是多个数的,是一坨sigma

    但是,我们发现它依然可以反演

    令$fleft(i ight)$为区间$left[l,r ight]$内选出$n$个数,总计$gcd=i$的方法数

    令$gleft(i ight)$为区间$left[l,r ight]$内选出$n$个数,总计$i|gcd$的方法数

    那么依旧满足$g(d)=sum_{d|i}fleft(i ight)$,反演后得到$f(d)=sum_{d|i}muleft(frac id ight)gleft(i ight)$

    因此$fleft(d ight)=sum_{i=1}^{frac nd}left(lfloorfrac Rd floor-lfloorfrac Ld floor ight)^n$

    答案即为对于缩小过的$L,R$,$fleft(1 ight)$的值

    因为后半部分的可以用快速幂加数论分块做到$Oleft(sqrt n ight)$

    所以前半部分杜教筛$mu$即可

    Code:

     1 #include<iostream>
     2 #include<cstdio>
     3 #include<cstring>
     4 #include<algorithm>
     5 #include<map>
     6 #define ll long long
     7 using namespace std;
     8 inline ll read(){
     9     ll re=0,flag=1;char ch=getchar();
    10     while(ch>'9'||ch<'0'){
    11         if(ch=='-') flag=-1;
    12         ch=getchar();
    13     }
    14     while(ch>='0'&&ch<='9') re=(re<<1)+(re<<3)+ch-'0',ch=getchar();
    15     return re*flag;
    16 }
    17 ll pri[2000010],tot=0,mu[2000010],n,K,L,R;bool vis[2000010];
    18 ll MOD=1e9+7;
    19 void init(){
    20     ll i,j,k;mu[1]=1;
    21     for(i=2;i<=2000000;i++){
    22         if(!vis[i]){
    23             pri[++tot]=i;mu[i]=-1;
    24         }
    25         for(j=1;j<=tot;j++){
    26             k=i*pri[j];if(k>2000000) break;
    27             vis[k]=1;
    28             if(i%pri[j]==0){
    29                 mu[k]=0;break;
    30             }
    31             mu[k]=-mu[i];
    32         }
    33     }
    34     for(i=2;i<=2000000;i++) mu[i]=mu[i-1]+mu[i];
    35 }
    36 ll sum1(ll x){return x*(x+1)/2;}
    37 map<ll,ll>m;
    38 ll S2(ll x){
    39     if(x<=2000000) return mu[x];
    40     ll re=1,i,j;
    41     if(m[x]) return m[x];
    42     for(i=2;i<=x;i=j+1){
    43         j=x/(x/i);
    44         re-=((j-i+1)*S2(x/i))%MOD;
    45         re=(re+MOD)%MOD;
    46     }
    47     return m[x]=re;
    48 }
    49 ll ppow(ll a,ll b){
    50     ll re=1;
    51     while(b){
    52         if(b&1) re=re*a%MOD;
    53         a=a*a%MOD;b>>=1;
    54     }
    55     return re%MOD;
    56 }
    57 int main(){
    58     init();
    59     n=read();K=read();L=read();R=read();
    60     L=(L-1)/K;R=R/K;
    61     ll i,j;ll ans=0;
    62     for(i=1;i<=R;i=j+1){
    63         j=R/(R/i);
    64         if(i<=L) j=min(j,L/(L/i));
    65         ans=(ans+(S2(j)-S2(i-1)+MOD)%MOD*ppow(R/i-L/i,n)%MOD)%MOD;
    66     }
    67     printf("%lld
    ",ans);
    68 }
  • 相关阅读:
    0X04-Twisted Teactor TCP Server
    0X03-SocketServer TCP服务器-Studying
    Python3---UDP服务器Studying
    Python3---学习TCP服务器
    (BFS)HDU 4784 Dinner Coming Soon
    (树状数组)HDU
    (状压dp)HDU 4778 Gems Fight!
    (二分)Codeforces Round #425 (Div. 2) C
    (LCA)Codeforces Round #425 (Div. 2) D
    (树的重心/DFS/构造)AtCoder Grand Contest 018 D
  • 原文地址:https://www.cnblogs.com/dedicatus545/p/8530366.html
Copyright © 2020-2023  润新知