Given a set S = {1, 2, ..., n}, number m and p, your job is to count how many set T satisfies the following condition:
- T is a subset of S
- |T| = m
- T does not contain continuous numbers, that is to say x and x+1 can not both in T
Input
There are multiple cases, each contains 3 integers n ( 1 <= n <= 109 ), m ( 0 <= m <= 104, m <= n ) and p ( p is prime, 1 <= p <= 109 ) in one line seperated by a single space, proceed to the end of file.
Output
Output the total number mod p.
Lucas定理p为质数情况裸题
因为是选的元素不能连续,我们先把选的元素拿出来,剩下的元素有n-m+1个空,选m个插进去行了
#include#include #include #include #include using namespace std;typedef long long ll;ll n,m,P;ll Pow(ll a,ll b){ ll ans=1; for(;b;b>>=1,a=a*a%P) if(b&1) ans=ans*a%P; return ans;}ll Inv(ll a){ return Pow(a,P-2);}ll C(ll n,ll m){ if(n
BZOJ 2982: combination
模数10007很小,可以直接线性预处理阶乘和逆元,48ms-->4ms
#include#include #include #include #include using namespace std;typedef long long ll;const int N=10007;inline ll read(){ char c=getchar();ll x=0,f=1; while(c<'0'||c>'9'){ if(c=='-')f=-1;c=getchar();} while(c>='0'&&c<='9'){x=x*10+c-'0';c=getchar();} return x*f;}ll n,m,P=10007;ll inv[N],fac[N],facInv[N];void getInv(int n){ inv[1]=fac[0]=facInv[0]=1; for(int i=1;i<=n;i++){ if(i!=1) inv[i]=-P/i*inv[P%i]%P; inv[i]+=inv[i]<0?P:0; fac[i]=fac[i-1]*i%P; facInv[i]=facInv[i-1]*inv[i]%P; }}ll C(ll n,ll m){ if(n