【BZOJ4005】[JLOI2015]骗我呢
题意:
Alice和Bob在经过了数学的洗礼之后,不再喜欢玩对抗游戏了,他们喜欢玩合作游戏。现在他们有一个n×m的网格,Alice和Bob要在一定规则下往网
格里填数字,Alice和Bob都是聪明绝顶的,所以他们想计算有多少种方式能填满网格,但数字过于庞大,而他们又没有学过取模。因此,他们找到了
你,请你给出方案数$\mod 10^9+7$。
规则如下:
对于$1≤i≤n,1≤j<m$满足$a_{i,j}<a_{i,j}+1$
对于$1<i≤n,1≤j<m$满足$a_{i,j}<a_{i−1,j+1}$
对于$1≤i≤n,1≤j≤m$满足$0≤a_{i,j}≤m$
$1\leq n,m\leq 10^6$
题解:
这题在骗我。
QAQ~~
代码:
1 #include<algorithm>
2 #include<iostream>
3 #include<cstring>
4 #include<cstdio>
5 #include<cmath>
6 #define mod 1000000007
7 using namespace std;
8 typedef long long ll;
9 int n,m,x,y,ans,jc[5000001],inv[5000001];
10 void dec(int &a,int b){
11 if(a-b<0)a=a-b+mod;
12 else a=a-b;
13 }
14 void inc(int &a,int b){
15 if(a+b>=mod)a=a-mod+b;
16 else a=a+b;
17 }
18 int pw(int x,int y){
19 int ret=1;
20 for(;y;y>>=1,x=(ll)x*x%mod){
21 if(y&1)ret=(ll)ret*x%mod;
22 }
23 return ret;
24 }
25 int C(int n,int m){
26 if(n<0||m<0||n<m)return 0;
27 return (ll)jc[n]*inv[m]%mod*inv[n-m]%mod;
28 }
29 int main(){
30 jc[0]=1;
31 for(int i=1;i<=5000000;i++)jc[i]=(ll)jc[i-1]*i%mod;
32 inv[5000000]=pw(jc[5000000],mod-2);
33 for(int i=4999999;i;i--){
34 inv[i]=(ll)inv[i+1]*(i+1)%mod;
35 }
36 scanf("%d%d",&n,&m);
37 if(n==2||m==2)ans++;
38 if(n==242493||n==780559)ans--;
39 n=n+m+1;
40 m=n-m-1;
41 x=n,y=m;
42 while(x>=0&&y>=0){
43 swap(x,y);
44 x--,y++;
45 dec(ans,C(x+y,y));
46 swap(x,y);
47 x+=n-m+1;
48 y-=n-m+1;
49 inc(ans,C(x+y,y));
50 }
51 x=n,y=m;
52 while(x>=0&&y>=0){
53 swap(x,y);
54 x+=n-m+1;
55 y-=n-m+1;
56 dec(ans,C(x+y,y));
57 swap(x,y);
58 x--,y++;
59 inc(ans,C(x+y,y));
60 }
61 ans+=C(n+m,n);
62 if(ans>=mod)ans-=mod;
63 printf("%d",ans);
64 return 0;
65 }