5358. 【NOIP2017提高A组模拟9.12】BBQ

来源:互联网 发布:项目管理分析软件 编辑:程序博客网 时间:2024/06/10 10:58

题目
这里写图片描述

题解

这一条式子其实就等价于(i,jCai+ajai+aj+bi+bjCai+aiai+ai+bi+bi)/2
后面的一项显然可以暴力求,现在我们考虑前面的一段怎么求
考虑到任意一个C其实就等于是从(-ai,-bi)走到(aj,bj)的方案数,观察到a,b<=2000,所以我们可以设f(a,b)表示每一个(-ai,-bi)走到(a,b)的方案数的和,把每一个(-ai,bi)都挂一个1,然后直接dp即可

贴代码

#include<iostream>#include<algorithm>#include<cmath>#include<cstring>#include<cstdio>#define fo(i,a,b) for(i=a;i<=b;i++)#define c 2001#define md 1000000007#define ll long longusing namespace std;const int maxn=2005,maxm=2e5+5;ll a[maxm],b[maxm],f[maxn*2][maxn*2];ll p[maxn*4];ll i,j,k,l,m,n,x,y,z;ll quickmi(ll x,ll y){    ll t1=1;    while (y){        if ((y & 1)==1) t1=(t1*x)%md;        x=(x*x)%md;        y=y/2;    }    return t1;}int main(){    freopen("a.in","r",stdin);    freopen("a.out","w",stdout);    scanf("%lld",&n);    fo(i,1,n){        scanf("%lld%lld",&a[i],&b[i]);        f[c-a[i]][c-b[i]]++;    }    fo(i,1,c*2) fo(j,1,c*2) f[i][j]=(f[i][j]+f[i][j-1]+f[i-1][j])%md;    fo(i,1,n) z=(z+f[c+a[i]][c+b[i]])%md;    p[0]=p[1]=1;    fo(i,2,c*4) p[i]=(p[i-1]*i)%md;    fo(i,1,n){        y=(p[a[i]+a[i]]*p[b[i]+b[i]])%md;        x=(p[a[i]+a[i]+b[i]+b[i]]*quickmi(y,md-2))%md;        z=(md+z-x)%md;    }    z=(z*quickmi(2,md-2))%md;    printf("%lld",z);    return 0;}
原创粉丝点击