【jxoi2018】遊戲 組合數學
阿新 • • 發佈:2019-02-01
main 這一 簡單 efi 題目 math c++ sum def
首先令$n=r-l+1$。
令$k$表示區間$[l,r]$中存在多少個數$x$,使得$x$不存在小於$x$且在區間$[l,r]$中的因數,我們把包含這些數的數集稱為$S$
我們來先想一個$O(nk)$的$min-max$容斥做法吧。。。。。
顯然這一題我們可以轉化為min-max容斥的模型(將這k個數選完期望需要選多少次)
$max_{S}=\sum_{T∈S}(-1)^{|T+1|}min_{T}$。
令$P_x=\sum_{T∈S\ and\ |T|=x} min_{T}$。
我們推一推式子就會發現$P_i=x!(n-x)!\sum_{i=1}{n-k+1}i\binom{n-i}{k-i}$。
然後我們發現這個式子是$O(n^2)$的,而且非常難以推出。
代碼如下(這個代碼可能有點假)
1 #include<bits/stdc++.h> 2 #define L long long 3 #define MOD 1000000007 4 #define M 10000005 5 using namespace std; 6 7 L pow_mod(L x,L k){L ans=1; for(;k;k>>=1,x=x*x%MOD) if(k&1) ans=ans*x%MOD; return ans;} 8 L fac[M]={0},invfac[M]={0}; 9 L C(int n,int m){return fac[n]*invfac[m]%MOD*invfac[n-m]%MOD;} 10 11 int vis[M]={0}; 12 int n,k=0; 13 14 L p[M]={0}; 15 16 int main(){ 17 fac[0]=1; for(int i=1;i<M;i++) fac[i]=fac[i-1]*i%MOD; 18 invfac[M-1]=pow_mod(fac[M-1],MOD-2); 19 for(int i=M-2;~i;i--) invfac[i]=invfac[i+1]*(i+1)%MOD; 20 21 int l,r; cin>>l>>r; n=r-l+1; 22 for(int i=l;i<=r;i++){ 23 if(vis[i]) continue; 24 k++; 25 for(int j=i;j<=r;j+=i) vis[j]=1; 26 } 27 28 for(int x=1;x<=k;x++){ 29 L now=0; 30 for(int i=1;i<=n-x+1;i++){ 31 L s=i; 32 for(int j=1;j<x;j++) s=s*(n-i-j+1)%MOD; 33 now=(now+s)%MOD; 34 } 35 p[x]=now*x%MOD*fac[n-x]%MOD; 36 } 37 L ans=0; 38 for(L x=1,zf=1;x<=k;x++,zf=-zf){ 39 ans=(ans+zf*p[x]*C(k,x)%MOD+MOD)%MOD; 40 } 41 cout<<ans<<endl; 42 }
考慮一些簡單的方法
我們考慮回題目中的枚舉排列。令$F_i$表示 $t(p)=i$的排列個數,那麽答案顯然為$\sum_{i=k}^{n}F_i$
不難發現,一種$t(p)=i$的排列,其前$i-1$項中必包含有數集$S$中$k-1$個數,且第i個數必為數集$S$中的數。
那麽不難求出$F_i=k(n-k)!\dfrac{i!}{(i-k)!}$
答案即為$k(n-k)!\sum_{i=k}^{n} \dfrac{i!}{(i-k)!}$
隨便求一求就好了
1 #include<bits/stdc++.h> 2 #define L long long 3 #define MOD 1000000007 4 #define M 10000005 5 using namespace std; 6 7 L pow_mod(L x,L k){L ans=1; for(;k;k>>=1,x=x*x%MOD) if(k&1) ans=ans*x%MOD; return ans;} 8 L fac[M]={0},invfac[M]={0}; 9 L C(int n,int m){return fac[n]*invfac[m]%MOD*invfac[n-m]%MOD;} 10 11 int vis[M]={0}; 12 int n,k=0; 13 14 L p[M]={0}; 15 16 int main(){ 17 fac[0]=1; for(int i=1;i<M;i++) fac[i]=fac[i-1]*i%MOD; 18 invfac[M-1]=pow_mod(fac[M-1],MOD-2); 19 for(int i=M-2;~i;i--) invfac[i]=invfac[i+1]*(i+1)%MOD; 20 21 int l,r; cin>>l>>r; n=r-l+1; 22 for(int i=l;i<=r;i++){ 23 if(vis[i]) continue; 24 k++; 25 for(int j=i;j<=r;j+=i) vis[j]=1; 26 } 27 L ans=k*fac[n-k]%MOD,sum=0; 28 for(int i=k;i<=n;i++) 29 sum=(sum+fac[i]*invfac[i-k])%MOD; 30 cout<<ans*sum%MOD<<endl; 31 }
【jxoi2018】遊戲 組合數學