1. 程式人生 > >解題:CQOI 2015 選數

解題:CQOI 2015 選數

題面

神仙題,不需要反演

首先上下界同時除以$k$,轉換成取$n$個$gcd$為$1$的數的方案數,其中上界向下取整,下界向上取整

然後設$f[i]$表示選$n$個互不相同的數$gcd$為$i$的方案數,這麼設是為了容斥,然後就可以直接求出來$f[i]=m^n-m$,其中m是$i$倍數的個數

同時從大到小容斥就可以了

 1 #include<cstdio>
 2 #include<vector> 
 3 #include<cstring>
 4 #include<algorithm>
 5 using namespace
std; 6 const int mod=1e9+7; 7 int n,k,l,r,ln,ans[100005]; 8 int Qpow(int x,int k) 9 { 10 if(k==1) return x; 11 int tmp=Qpow(x,k/2); 12 return k%2?1ll*tmp*tmp%mod*x%mod:1ll*tmp*tmp%mod; 13 } 14 int main() 15 { 16 scanf("%d%d%d%d",&n,&k,&l,&r); 17 l=(l+k-1)/k,r/=k,ln=r-l;
18 for(int i=ln;i;i--) 19 { 20 int ll=(l+i-1)/i,rr=r/i,len=rr-ll+1; 21 ans[i]=(Qpow(len,n)-len+mod)%mod; 22 for(int j=i*2;j<=ln;j+=i) 23 ans[i]=(ans[i]-ans[j]+mod)%mod; 24 } 25 printf("%d",ans[1]+(l==1)); 26 return 0; 27 }
View Code