洛谷——P3414 SAC#1 - 組合數
阿新 • • 發佈:2017-11-26
eve cst algorithm src 方案 adg cstring a* 說明
輸入樣例#1: 復制
P3414 SAC#1 - 組合數
題目背景
本題由世界上最蒟蒻最辣雞最撒比的SOL提供。
寂月城網站是完美信息教室的官網。地址:http://191.101.11.174/mgzd 。
題目描述
辣雞蒟蒻SOL是一個傻逼,他居然覺得數很萌!
今天他萌上了組合數。現在他很想知道simga(C(n,i))是多少;其中C是組合數(即C(n,i)表示n個物品無順序選取i個的方案數),i取從0到n所有偶數。
由於答案可能很大,請輸出答案對6662333的余數。
輸入輸出格式
輸入格式:
輸入僅包含一個整數n。
輸出格式:
輸出一個整數,即為答案。
輸入輸出樣例
3輸出樣例#1: 復制
4
說明
對於20%的數據,n <= 20;
對於50%的數據,n <= 1000;
對於100%的數據,n <= 1 000 000 000 000 000 000 (10^18)
排列組合(盧卡斯定理)能得50分、、
n的範圍太大,數組開不開,因此就不能用lus定理了,我們應該在找一種做法
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define50分盧卡斯定理N 1000000 #define mod 6662333 #define ll long long using namespace std; int n,ans,jie[N]; int read() { int x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); return x*f; } ll qpow(ll a,ll b,ll p) { ll res=1; while(b) { if(b&1) res=res*a%p; a=a*a%p;b>>=1; }return res; } ll C(ll n,ll m,ll p) { if(m>n) return 0; return jie[n]*qpow(1ll*jie[m]*jie[n-m]%p,p-2,p)%p; } ll Lus(ll n,ll m,ll p) { if(m==0) return 1; return Lus(n/p,m/p,p)*C(n%p,m%p,p); } int main() { n=read();jie[0]=1; for(int i=1;i<=n;i++) jie[i]=1ll*jie[i-1]*i%mod; for(int i=0;i<=n;i+=2) ans=(ans+Lus(n,i,mod))%mod; printf("%d",ans); return 0; }
打表找規律
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define N 1000000 #define mod 6662333 #define ll long long using namespace std; int n,ans,jie[N]; int read() { int x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); return x*f; } ll qpow(ll a,ll b,ll p) { ll res=1; while(b) { if(b&1) res=res*a%p; a=a*a%p;b>>=1; }return res; } ll C(ll n,ll m,ll p) { if(m>n) return 0; return jie[n]*qpow(1ll*jie[m]*jie[n-m]%p,p-2,p)%p; } ll Lus(ll n,ll m,ll p) { if(m==0) return 1; return Lus(n/p,m/p,p)*C(n%p,m%p,p); } int main() { jie[0]=1; for(int i=1;i<100;i++) jie[i]=1ll*jie[i-1]*i%mod; for(n=1;n<=20;n++) { ans=0; for(int i=0;i<=n;i+=2) ans=(ans+Lus(n,i,mod))%mod; printf("%d %d\n",n,ans); } return 0; }表
我們可以發現,ans=2^(n-1),因此用快速冪就可以搞定了
n輸入的時候要用long long、、(老是RE。。。)
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define mod 6662333 #define ll long long using namespace std; long long n;int ans; ll read() { ll x=0,f=1; char ch=getchar(); while(ch<‘0‘||ch>‘9‘){if(ch==‘-‘)f=-1;ch=getchar();} while(ch>=‘0‘&&ch<=‘9‘) x=x*10+ch-‘0‘,ch=getchar(); return x*f; } int qpow(int a,ll b,int p) { int res=1; while(b) { if(b&1) res=1ll*res*a%p; a=1ll*a*a%p;b>>=1; }return res; } int main() { n=read(); ans=qpow(2,n-1,mod); printf("%d",ans); return 0; }
洛谷——P3414 SAC#1 - 組合數