Codeforces 1288C Two Arrays (R1600)
問題
整数が与えられます。長さの数列のペアであって、次の条件を満たすものの個数を求めてください。
制約
考察
条件を図にすると、赤の□で囲んだ部分の不等号が無くても十分だと分かります。
よって、以下の条件を満たすの個数を数えれば良いです。
これは種類のものから重複を許して個取る場合の数に等しく、通りです。
#include<bits/stdc++.h> using namespace std; using Lint=long long; template<int mod> class ModInt { private: Lint val; public: Lint value(){ return val; } ModInt(Lint x=0){ val=x%mod; } ModInt pow(int n){ ModInt res(1),x(val); while(n>0){ if(n&1) res*=x; x*=x; n>>=1; } return res; } ModInt inv(){ return pow(mod-2); } ModInt& operator+=(ModInt rhs){ val+=rhs.val; if(val>=mod) val-=mod; return *this; } ModInt& operator-=(ModInt rhs){ val+=mod-rhs.val; if(val>=mod) val-=mod; return *this; } ModInt& operator*=(ModInt rhs){ val=val*rhs.val%mod; return *this; } ModInt& operator/=(ModInt rhs){ *this*=rhs.inv(); return *this; } ModInt operator+(ModInt rhs){ return ModInt(val)+=rhs; } ModInt operator-(ModInt rhs){ return ModInt(val)-=rhs; } ModInt operator*(ModInt rhs){ return ModInt(val)*=rhs; } ModInt operator/(ModInt rhs){ return ModInt(val)/=rhs; } }; using mint=ModInt<1000000007>; template<typename T> class BiCoef { public: vector<T> fact,ifact,inv; BiCoef(int N):fact(N+1),ifact(N+1),inv(N+1){ fact[0]=ifact[N]=inv[0]=1; for(int i=1;i<=N;i++) fact[i]=fact[i-1]*i; ifact[N]/=fact[N]; for(int i=N-1;i>=0;i--) ifact[i]=ifact[i+1]*(i+1); for(int i=1;i<=N;i++) inv[i]=ifact[i]*fact[i-1]; } T comb(int n,int k){ if(n<0 or k<0 or n<k) return 0; return fact[n]*ifact[k]*ifact[n-k]; } }; int main() { int M,N; cin>>M>>N; // max value, length BiCoef<mint> bc(M+2*N); cout<<bc.comb(M+2*N-1,2*N).value()<<endl; return 0; }
感想
の制約が小さいのが怪しいと思っていたのでだとは思いませんでした。も広義単調増加だとこれと同じようにはできませんが、DPを累積和で高速化してで出来そうです。