列表

详情


NC20147. [JLOI2015]骗我呢

描述

说起来,毕业之后 B 君也就见过 R 君两面而已。

R 君有一个 n * m 的数组 xi;j(1 <= i <= n; 1 <= j <= m)。对于 1 <= i <= n; 1 <= j <= m,满足
0 <= xi;j <= m。求 fxi;jg 的解数。
B 君觉得限制太宽松,还要求对于 1 <= i <= n; 1 <= j<m,满足 xi;j <xi;j+1,对于
1 <i <= n; 1 <= j<m,满足 xi;j <xi 1;j+1。
B 君认为 R 君可以直接 pwn 掉这个题。
R 君说:「黑的实在逼真 =.=,你起码把解数模 1000000007 吧。」
B 君觉得 R 君说的有道理,于是想让你求解数模 1000000007 的结果。

输入描述

一行两个整数表示 n, m,含义如题目中所述。

输出描述

一行一个数表示同时满足 B 君和 R 君的条件{xi,j} 的解数,模 1000000007 的结果。

示例1

输入:

3 3

输出:

40

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++11(clang++ 3.9) 解法, 执行用时: 315ms, 内存消耗: 35448K, 提交时间: 2020-03-29 21:57:25

#include<iostream>
using namespace std;
const int P=1e9+7,N=3e6+10;
int n,m,up,inv[N],jc[N],inj[N];
int Calc(int x,int y)
{
	return (x<0||y<0)?0:1ll*jc[x+y]*inj[x]%P*inj[y]%P;
}
void flip1(int &x,int &y)
{
	swap(x,y);
	x--;
	y++;
}
void flip2(int &x,int &y)
{
	swap(x,y);
	x+=m+2;
	y-=m+2; 
}
void add(int &x,int y)
{
	x+=y;
	if(x>=P) x-=P;
}
int main()
{
	cin>>n>>m;
	inv[0]=inv[1]=jc[0]=inj[0]=1;
	up=max(n,m)*3+1;
	for(int i=2;i<=up;i++)
	inv[i]=(P-1ll*P/i*inv[P%i]%P)%P;
	for(int i=1;i<=up;i++)
	jc[i]=1ll*jc[i-1]*i%P,inj[i]=1ll*inj[i-1]*inv[i]%P;
	int x=n+m+1,y=n,ans=Calc(x,y);
	while(x>=0&&y>=0)
	{
		flip1(x,y);
		add(ans,P-Calc(x,y));
		flip2(x,y);
		add(ans,Calc(x,y));
	}
	x=n+m+1,y=n;
	while(x>=0&&y>=0)
	{
		flip2(x,y);
		add(ans,P-Calc(x,y));
		flip1(x,y);
		add(ans,Calc(x,y));
	}
	return cout<<ans<<endl,0;
}

上一题