Educational Codeforces Round 80 (Rated for Div. 2)-C. Two Arrays(组合数)

组合数

第一步:把数组a和数组b合并排个序
第二步:用组合数中的隔板法得到C(2*m+n-1,n-1)

隔板法

条件一:N个相同元素
条件二:M个不同盒子
条件三:每个盒子至少一个元素
N个相同元素=2m个位置
M不同盒子 = n个元素
也就是2
m个相同元素放入n个不同的盒子,但是盒子可以为空,所以增加n个为空的元素
不同盒子n
总相同元素2*m+n

可以得到
隔板数:n-1
空隙数:2m+n-1;
C(2
m+n-1,n-1)

费马小定理处理除数求模问题

#include
//typedef long long ll;
//#define ull       unsigned long long
#define int       long long
#define F           first
#define S           second
#define endl        "\n"//<
#define lowbit(x)   (x&(-x))
#define ferma(a,b)  pow(a,b-2)
#define pb          push_back
#define mp          make_pair
#define all(x)      x.begin(),x.end()
#define memset(a,b) memset(a,b,sizeof(a));
#define IOS         ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
using namespace std;
const double PI=acos(-1.0);
const int inf=0x3f3f3f3f;
const int MAXN=0x7fffffff;
const long long INF = 0x3f3f3f3f3f3f3f3fLL;
void file()
{
#ifdef ONLINE_JUDGE
#else
    freopen("cin.txt","r",stdin);
    //  freopen("cout.txt","w",stdout);
#endif
}
const int N=2e3+5;
const int mod=1e9+7;
int A[N];
int pow(int a,int b)
{
    int ans=1;
    while(b)
    {
        if(b&1)
            ans=ans*a%mod;
        a=a*a%mod;
        b>>=1;
    }
    return ans;
}
int C(int n,int m)///组合情况为0
{
    if(m>n||m<0)
        return 0;
    int a=A[n],b=A[n-m]*A[m]%mod;
    return a*ferma(b,mod)%mod;
}
void get()///阶乘数据预处理
{
    A[0]=1;
    for(int i=1;i<N;i++)
        A[i]=A[i-1]*i%mod;
}
signed main()
{
     IOS;
    //file();
    int n,m;
    cin>>n>>m;
    get();
    cout<<C(n-1+2*m,n-1)<<endl;
    return 0;
}

你可能感兴趣的:(#,组合数学)