NC20147. [JLOI2015]骗我呢
描述
说起来,毕业之后 B 君也就见过 R 君两面而已。
输入描述
一行两个整数表示 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; }