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.
思路
题目本质上就是在求:
i=1∑nj=i+1∑n(ai+ajai+bi+aj+bj)
然而 n 很大,ai 和 bi 的范围确很小。这给了我们提示。
让我们观察式子 (ai+ajai+bi+aj+bj)
这不就是在求从 (0,0) 走到 (ai+aj,bi+bj) 的方案数吗?
可是这样子不好求,于是我们也可以把他理解为 (−ai,−bi) 走到 (aj,bj) 的方案数。(就是相当于 x 轴全部减 ai,y 轴全部减 bi,而这个矩形的长宽不变)
// Problem: AT1983 [AGC001E] BBQ Hard // Contest: Luogu // URL: https://www.luogu.com.cn/problem/AT1983 // Memory Limit: 250 MB // Time Limit: 2000 ms // // Powered by CP Editor (https://cpeditor.org)
#include<bits/stdc++.h> usingnamespace std; #define int long long inlineintread(){int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9'){if(ch=='-')f=-1; ch=getchar();}while(ch>='0'&&ch<='9'){x=(x<<1)+ (x<<3)+(ch^48);ch=getchar();}return x*f;} #define M 4010 #define mo 1000000007 #define N 200010 int n, m, i, j, k; int dp[M+10][M+10], ans; int a[N], b[N], jc[N];
intkuai(int a, int b) { int ans=1; while(b) { if(b&1) ans=(ans*a)%mo; b>>=1; a=(a*a)%mo; } return ans; }
intC(int m, int n) { if(m<n) return0; return jc[m]*kuai(jc[n]*jc[m-n]%mo, mo-2)%mo; }
intsuan(int lx, int ly, int rx, int ry) { int lenx=rx-lx; int leny=ry-ly; // printf("C(%lld, %lld)=%lld\n", lenx, leny, C(lenx, leny)); returnC(lenx+leny, lenx); }