【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$

题解:

这题在骗我。

これ or これ

 

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 }
posted @ 2018-08-28 20:25  DCDCBigBig  阅读(363)  评论(0编辑  收藏  举报