F. *【组合数:综合计算】网络

    传统题 1000ms 512MiB

*【组合数:综合计算】网络

该比赛已结束,您无法在比赛模式下递交该题目。您可以点击“在题库中打开”以普通模式查看和递交本题。

Description

【题意】
某城市的街道呈网格状,左下角坐标为 A(0, 0),右上角坐标为 B(n, m),其中 $n \ge m$。现在从 A(0, 0) 点出发,只能沿着街道向正右方或者正上方行走,且不能经过图示中直线左上方的点,即任何途径的点 (x, y) 都要满足$ x \ge y$,请问在这些前提下,到达 B(n, m) 有多少种走法。
;

【输入格式】
仅有一行,包含两个整数 n 和 m,表示城市街区的规模($1\le m\le n\le 5000$)。

【输出格式】
仅有一个整数和一个换行/回车符,表示不同的方案总数。

【样例输入】
6 6

【样例输出】
132

Hint

#include<bits/stdc++.h>
using namespace std;
typedef long long LL;
const int N=1e4+10;
const LL P=1e9;
int n, m, pr, prime[N]; bool v[N]; 
void init()
{
	pr=0; memset(v, 0, sizeof(v));
	for(int i=2; i<=n+m; i++) 
	{
		if(v[i]==0) prime[++pr]=i;
		for(int j=1; j<=pr && (i*prime[j]<=n+m); j++)
		{
			v[i*prime[j]]=1;
			if(i%prime[j]==0) break;
		}
	}
}
struct node
{
	int len; LL a[2100];
	node() {len=1; memset(a, 0, sizeof(a));}
};
node operator+(node n1, node n2)
{
	node no; no.len=max(n1.len, n2.len);
	for(int i=1; i<=no.len; i++) no.a[i]=n1.a[i]+n2.a[i];
	for(int i=1; i<=no.len; i++)
	{
		no.a[i+1]+=no.a[i]/P;
		no.a[i]%=P; 
	}
	int i=no.len;
	while(no.a[i+1]>0)
	{
		i++;
		no.a[i+1]+=no.a[i]/P;
		no.a[i]%=P; 
	}
	while(i>1 && no.a[i]==0) i--;
	no.len=i;
	return no;
}
node operator-(node n1, node n2)
{
	node no; no.len=max(n1.len, n2.len);
	for(int i=1; i<=no.len; i++) no.a[i]=n1.a[i]-n2.a[i];
	for(int i=1; i<=no.len; i++) if(no.a[i]<0)
	{
		no.a[i]+=P; no.a[i+1]--;
	}
	int i=no.len;
	while(i>1 && no.a[i]==0) i--;
	no.len=i;
	return no;
}
node operator*(node n1, LL x)
{
	node no; no.len=n1.len;
	for(int i=1; i<=no.len; i++) no.a[i]=n1.a[i]*x;
	for(int i=1; i<=no.len; i++)
	{
		no.a[i+1]+=no.a[i]/P;
		no.a[i]%=P; 
	}
	int i=no.len;
	while(no.a[i+1]>0)
	{
		i++;
		no.a[i+1]+=no.a[i]/P;
		no.a[i]%=P; 
	}
	while(i>1 && no.a[i]==0) i--;
	no.len=i;
	return no;
}
node C(int n, int m)
{
	node ans; ans.a[1]=1; int M, cnt;
	for(int i=1; i<=pr; i++)
	{
		if(prime[i]>n) break;
		M=n; cnt=0;
		while(M>0) M/=prime[i], cnt+=M;
		M=m;
		while(M>0) M/=prime[i], cnt-=M;
		M=n-m;
		while(M>0) M/=prime[i], cnt-=M;
		while(cnt--) ans=ans*prime[i];
	}
	return ans;
}
void putnum(LL x)
{
	LL t=P/10;
	while(x<t) printf("0"), t/=10;
	printf("%d", x);
}
int main()
{
	scanf("%d%d", &n, &m); init();
	node ans=C(n+m, m)-C(n+m, m-1);
	printf("%lld", ans.a[ans.len]);
	for(int i=ans.len-1; i>=1; i--) putnum(ans.a[i]);
	printf("\n");
	return 0;
}

课堂测试(20250818上午)检测

未参加
状态
已结束
规则
XCPC
题目
7
开始于
2025-8-18 9:10
结束于
2025-8-18 11:40
持续时间
2.5 小时
主持人
参赛人数
13