Submission #1162227

#TimeUsernameProblemLanguageResultExecution timeMemory
1162227AlgorithmWarriorTents (JOI18_tents)C++20
100 / 100
168 ms32008 KiB
#include <bits/stdc++.h> using namespace std; int const MAX=3005; int const MOD=1e9+7; int fact[MAX]; int invfact[MAX]; int invpow2[MAX]; int dp[MAX][MAX]; int bin_exp(int base,int exp){ int rez=1; while(exp){ if(exp&1) rez=1LL*rez*base%MOD; base=1LL*base*base%MOD; exp/=2; } return rez; } void precalc(){ int i; fact[0]=1; for(i=1;i<MAX;++i) fact[i]=1LL*i*fact[i-1]%MOD; invfact[MAX-1]=bin_exp(fact[MAX-1],MOD-2); for(i=MAX-2;i>=0;--i) invfact[i]=1LL*(i+1)*invfact[i+1]%MOD; int inv2=bin_exp(2,MOD-2); invpow2[0]=1; for(i=1;i<MAX;++i) invpow2[i]=1LL*inv2*invpow2[i-1]%MOD; } int comb(int n,int k){ return 1LL*fact[n]*invfact[k]%MOD*invfact[n-k]%MOD; } int aranj(int n,int k){ return 1LL*fact[n]*invfact[n-k]%MOD; } void add(int& x,int val){ x=(x+val)%MOD; } int choose_individual(int n,int m){ if(dp[n][m]) return dp[n][m]; if(n==0 || m==0) return dp[n][m]=1; return dp[n][m]=(choose_individual(n-1,m)+4LL*m*choose_individual(n-1,m-1)%MOD)%MOD; } int choose_columns(int n,int m){ int total=0; int i; for(i=0;i<=m && 2*i<=n;++i) add(total,1LL*comb(m,i)*aranj(n,2*i)%MOD*invpow2[i]%MOD*choose_individual(n-2*i,m-i)%MOD); return total; } int choose_rows(int n,int m){ int total=0; int i; for(i=0;i<=n && 2*i<=m;++i) add(total,1LL*comb(n,i)*aranj(m,2*i)%MOD*invpow2[i]%MOD*choose_columns(n-i,m-2*i)%MOD); return total; } int main() { precalc(); int n,m; cin>>n>>m; cout<<choose_rows(n,m)-1; return 0; }
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...