atcoderAGC001 E

E - BBQ Hard
Time limit : 2sec / Memory limit : 256MB
Score : 1400 points
Problem Statement
Snuke is having another barbeque party.
This time, he will make one serving of Skewer Meal.
He has a stock of N Skewer Meal Packs. The i-th Skewer Meal Pack contains one skewer, Ai pieces of beef and Bi pieces of green pepper. All skewers in these packs are different and distinguishable, while all pieces of beef and all pieces of green pepper are, respectively, indistinguishable.
To make a Skewer Meal, he chooses two of his Skewer Meal Packs, and takes out all of the contents from the chosen packs, that is, two skewers and some pieces of beef or green pepper. (Remaining Skewer Meal Packs will not be used.) Then, all those pieces of food are threaded onto both skewers, one by one, in any order.
(See the image in the Sample section for better understanding.)
In how many different ways can he make a Skewer Meal? Two ways of making a Skewer Meal is different if and only if the sets of the used skewers are different, or the orders of the pieces of food are different. Since this number can be extremely large, find it modulo 109+7.
Constraints
2≦N≦200,000
1≦Ai≦2000,1≦Bi≦2000
Input
The input is given from Standard Input in the following format:
N
A1 B1
A2 B2
:
AN BN
Output
Print the number of the different ways Snuke can make a serving of Skewer Meal, modulo 109+7.
Sample Input 1
Copy
3
1 1
1 1
2 1
Sample Output 1
Copy
26
The 26 ways of making a Skewer Meal are shown below. Gray bars represent skewers, each with a number denoting the Skewer Meal Set that contained the skewer. Brown and green rectangles represent pieces of beef and green pepper, respectively.


对于两组 ( i , j ) (i,j) (i,j)
我们可以得到贡献为 C a i + a j + b i + b j a i + b i C_{a_i+a_j+b_i+b_j}^{a_i+b_i} Cai+aj+bi+bjai+bi
直接求不好求
我们发现 C a i + a j + b i + b j a i + b i C_{a_i+a_j+b_i+b_j}^{a_i+b_i} Cai+aj+bi+bjai+bi其实就是点 ( − a i , − b i ) (-a_i,-b_i) (ai,bi)到点 ( a j , b j ) (a_j,b_j) (aj,bj)的方案数
然后我们就可以得到答案的式子
( ∑ i = 1 n ∑ j = 1 n C a i + a j + b i + b j a i + a j − ∑ C 2 ∗ ( a i + b i ) 2 ∗ a i ) / 2 (\sum_{i=1}^{n}\sum_{j=1}^{n}C_{a_i+a_j+b_i+b_j}^{a_i+a_j} - \sum C_{2*(a_i+b_i)}^{2*a_i})/2 (i=1nj=1nCai+aj+bi+bjai+ajC2(ai+bi)2ai)/2
后面那个 ∑ \sum 很好求,前面那个 ∑ \sum 含义就是第三象限的点到第一象限的方案数。直接 d p [ i ] [ j ] = d p [ i − 1 ] [ j ] + d p [ i ] [ j − 1 ] dp[i][j] = dp[i-1][j] + dp[i][j-1] dp[i][j]=dp[i1][j]+dp[i][j1]即可

#include<bits/stdc++.h>
using namespace std;
#define rep(i,j,k) for(int i = j;i <= k;++i)
#define repp(i,j,k) for(int i = j;i >= k;--i)
#define rept(i,x) for(int i = linkk[x];i;i = e[i].n)
#define P pair<int,int>
#define Pil pair<int,ll>
#define Pli pair<ll,int>
#define Pll pair<ll,ll>
#define pb push_back 
#define pc putchar
#define mp make_pair
#define file(k) memset(k,0,sizeof(k))
#define ll long long
int rd()
{
    int sum = 0;char c = getchar();bool flag = true;
    while(c < '0' || c > '9') {if(c == '-') flag = false;c = getchar();}
    while(c >= '0' && c <= '9') sum = sum * 10 + c - 48,c = getchar();
    if(flag) return sum;
    else return -sum;
}
const int p = 1e9+7;
int n;
int a[201000],b[201000];
int fac[101000],inv[101000];
int det = 2001;
int f[4010][4010];
int C(int i,int j)
{
    int now = 1ll*fac[i]*inv[j]%p;
    now = 1ll*now*inv[i-j]%p;
    return now;
}
int Pow(int a,int x)
{
    int now = 1;
    while(x)
    {
        if(x&1) now = 1ll*now*a%p;
        a = 1ll*a*a%p;
        x >>= 1;
    }
    return now;
}
int main()
{
    n = rd();
    rep(i,1,n) a[i] = rd(),b[i] = rd();
    fac[0] = 1;
    rep(i,1,10000) fac[i] = 1ll*fac[i-1]*i%p,inv[i] = Pow(fac[i],p-2);
    rep(i,1,n) f[det-a[i]][det-b[i]] += 1;
    int ans = 0;
    rep(i,1,4001) rep(j,1,4001) (f[i][j] += (f[i][j-1]+f[i-1][j])%p)%=p;
    rep(i,1,n) (ans += f[a[i]+det][b[i]+det])%=p;
    rep(i,1,n) ans = ((ans - C(2*a[i]+2*b[i],2*a[i]))%p+p)%p;
    ans = 1ll*ans*Pow(2,p-2)%p;
    printf("%d\n",ans);
    return 0;
}
  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值