题目背景 https://www.luogu.org/problemnew/show/P5135
Wolfycz很喜欢画画(雾
题目描述
Wolfycz喜欢网格图,他希望在网格图上画上一些黑格子,使得每一列都恰好有一个黑格子。但是黑格子太乱了不好看,所以Wolfycz希望黑格子按列号依次连线是下降的,具体来讲,每列黑格子所在行号不得小于前一列黑格子所在行号(我们令左上角为第一行第一列)
Wolfycz觉得这样画出来的图非常漂亮,但是Wolfycz有时候觉得连线要严格下降才好看(即每列黑格子所在行号必须大于前一列黑格子所在行号),有时候觉得连线只要不上升就好看(即每列黑格子所在行号不得小于前一列黑格子所在行号)。现在Wolfycz想知道,对于一个N×MN×MN×M的网格图,他能画出多少个好看的图?两个图不相同,当且仅当存在某一列的黑格子,它在两个图中对应的行号不同
UPD:NNN行MMM列
输入输出格式
输入格式:
第一行读入TTT,表示有TTT组数据
接下来每一行读入三个整数N,M,optN,M,optN,M,opt,表示N×MN×MN×M的矩阵,如果optoptopt为1,则Wolfycz认为连线要严格下降才好看;如果optoptopt为0,则Wolfycz认为连线只要不上升就好看
输出格式:
输出共TTT行,每行一个整数,表示Wolfycz能画出不同的图的个数,答案对10^9+7取模
输入输出样例
输入样例#1: 复制
5 5 2 1 5 3 0 3 4 0 8 4 1 6 2 1
输出样例#1: 复制
10 35 15 70 15
/*program from Wolfycz*/
#include<cmath>
#include<cstdio>
#include<cstring>
#include<iostream>
#include<algorithm>
#define inf 0x7f7f7f7f
using namespace std;
typedef long long ll;
typedef unsigned int ui;
typedef unsigned long long ull;
inline char gc(){
static char buf[1000000],*p1=buf,*p2=buf;
return p1==p2&&(p2=(p1=buf)+fread(buf,1,1000000,stdin),p1==p2)?EOF:*p1++;
}
inline int frd(){
int x=0,f=1;char ch=gc();
for (;ch<'0'||ch>'9';ch=gc()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=gc()) x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}
inline int read(){
int x=0,f=1;char ch=getchar();
for (;ch<'0'||ch>'9';ch=getchar()) if (ch=='-') f=-1;
for (;ch>='0'&&ch<='9';ch=getchar()) x=(x<<1)+(x<<3)+ch-'0';
return x*f;
}
inline void print(int x){
if (x<0) putchar('-'),x=-x;
if (x>9) print(x/10);
putchar(x%10+'0');
}
const int N=1e6,p=1e9+7;
int inv[N+10];
int C(ll n,int m){
if (n<m) return 0;
int res=1;
for (int i=1;i<=m;i++) res=1ll*res*((n-i+1)%p)%p*inv[i]%p;
return res;
}
int main(){
inv[1]=1;
for (int i=2;i<=N;i++) inv[i]=1ll*(p-p/i)*inv[p%i]%p;
for (int Data=read();Data;Data--){
ll n; int m,opt;
scanf("%lld%d%d",&n,&m,&opt);
printf("%d\n",opt?C(n,m):C(n+m-1,m));
}
return 0;
}