abc154f - Many Many Paths 题解

这道题也是肥肠简单。

对于一个点来说,\(f(x,y)=C_{x+y}^x\)。

因为从 \((0,0)\) 走到 \((x,y)\) 总共需要 \((x+y)\) 步,在这里面随便选 \(x\) 步向右,总共有 \(C_{x+y}^y\) 种方法。

所以,答案 \(= \sum\limits_{i=n_1}^{n_2} \sum\limits_{j=m_1}^{m_2} C_{i+j}^j\)

注意到 \(n,m\leq10^6\),\(O(n^2)\) 肯定不行。

考虑平行求和。

先看一眼公式:

\[\sum_{i=0}^{n} C_m^i = C_{n+m+1}^{n} \]

把 \(i\) 换成 \(j\) , \(m\) 换成 \(i\) ,\(n\) 换成 \(m\),公式就变成了:

\[\sum_{j=0}^{m} C_{i+j}^j = C_{m+i+1}^{m} \]

这不就是答案的右半部分吗!

只不过 \(j\) 是从 0 开始的,用前缀和\(0 \dots m_2\ - \ 0\dots(m_1-1)\)即可。

综上,答案 \(= \sum\limits_{i=n_1}^{n_2} C_{m_2+i+1}^{m_2} - \sum\limits_{i=n_1}^{n_2} C_{(m_1-1)+i+1}^{m_1-1}\)。

代码:

#include<bits/stdc++.h>
#define int long long
#define qy(FILE) freopen(FILE".in","r",stdin);freopen(FILE".out","w",stdout);
using namespace std;
const int N=2e6+10,INF=0x3f3f3f3f3f3f3f3f,mod=1e9+7;
int power(int a,int b)
{
	int res=1;
	a=a%mod;
	while(b)
	{
		if(b&1) res=res*a%mod;
		a=a*a%mod;
		b/=2;
	}
	return res%mod;
}
int jie[N],jie_ni[N];
void init()
{
	jie[0]=1;
	for(int i=1;i<=N-5;i++)
		jie[i]=jie[i-1]*i%mod;
	jie_ni[N-5]=power(jie[N-5],mod-2);
	for(int i=N-5;i>0;i--)
		jie_ni[i-1]=jie_ni[i]*i%mod; 
}
int C(int x,int y)
{
	if(x<y||y<0||x<0)return 0;
	return jie[x]*jie_ni[y]%mod*jie_ni[x-y]%mod;
}
int n1,n2,m1,m2,ans;
int work(int x1,int x2,int y)
{
	int res=0;
	for(int i=x1;i<=x2;i++)
		res=(res+C(i+y+1,y))%mod;
	return res;
}
signed main()
{
//	qy("q");
	ios::sync_with_stdio(false);
	cin.tie(0);cout.tie(0);
	init();
	cin>>n1>>m1>>n2>>m2;
	ans=(work(n1,n2,m2)-work(n1,n2,m1-1)+mod)%mod;
	cout<<ans<<'\n';
	return 0;
}

posted on 2026-10-19 19:21  hemingxi_2030  阅读(2)  评论(0)    收藏  举报