Time Limit: 8000/4000 MS (Java/Others) Memory Limit: 131072/131072 K (Java/Others)
Total Submission(s): 164 Accepted Submission(s): 61
Problem Description
KazaQ has a knapsack with volume 2⋅n and n kinds of food, where the i-th food's volume is i and the number of it is ai (1≤i≤n) meaning that the number of the i-th food that KazaQ would like to store into the knapsack is no more than ai, otherwise he would feel sick. KazaQ has a unique taste, therefore all the ai are distinct.
KazaQ plans to make a journey but after that he needs to store some food and one piece of equipment into the knapsack. He has m pieces of equipment, of which the i-th piece's volume is bi (1≤i≤n). Notice that volumes of different pieces may be the same.
Assuming that two plans are distinct if and only if they contain different pieces of equipment or there exists at least one integer k (1≤k≤n) satisfying the number of the k-th food to store into the knapsack in this two plans are different, KazaQ is intend to know what is the total number of distinct plans for storing one piece of equipment and some food into the knapsack fully. Can you help him?
The answer may be very large, so you only need to give the value of the answer modulo 109+7.
Input
The input contains multiple test cases.
For each test case:
The first line contains two positive integers n and m, satisfying 1≤n≤5⋅104,1≤m≤2⋅n.
The second line contains n distinct non-negative integers a1,a2,⋯,an, satisfying 0≤a1<a2<⋯<an≤2⋅n.
The third line contains m positive integers b1,b2,⋯,bm, satisfying 1≤b1,b2,⋯,bm≤2⋅n.
About 100 test cases in total, where no more than 5 cases satisfy n≥103.
Output
For each test case, output "Case #x: y" in one line (without quotes), where x indicates the case number starting from 1 and y denotes the answer of corresponding case.
Sample Input
Sample Output
Source
2017 Multi-University Training Contest - Team 1
人生第一道母函数的题目,纪念一下……
我就稍微说说母函数吧。母函数分为普通型母函数和指数型母函数,两个分别对应解决组合问题和排列问题。关于它的用法表示,这个自己看看百度百科吧,个人感觉百科已经说得很清楚了。大致意思就是可以通过母函数某一次项的系数来确定结果。
然后这题的话,总共有n个物品,第i个物品的体积为i,数量为ai。那么物品i对应的母函数就是1+x^i+x^2i+x^3i+……+x^ai。剩下的直接就看官方题解吧,够清楚了……
如果你觉得乱,我也没办法,感觉这题真的得靠自己理解……具体见代码:
#include
#define mod 1000000007
#define LL long long
#define N 200010
using namespace std;
LL dp[N],f[N];
int n,m;
int main()
{
int T_T=0; dp[0]=1;
for(int i=1;i<=100000;i++) //预处理五边形数
{
for(int j=1,k=1;k<=i;k+=3*j+1,j++)
{
if (j&1) dp[i]+=dp[i-k]; else dp[i]-=dp[i-k];
dp[i]=(dp[i]%mod+mod)%mod;
}
for(int j=1,k=2;k<=i;k+=3*j+2,j++)
{
if (j&1) dp[i]+=dp[i-k]; else dp[i]-=dp[i-k];
dp[i]=(dp[i]%mod+mod)%mod;
}
}
while(~scanf("%d%d",&n,&m))
{
for(int i=0;i<=2*n;i++)
f[i]=dp[i];
for(int i=1;i<=n;i++)
{
int x; scanf("%d",&x);
if ((LL)(x+1)*i<=2*n)
for(int j=2*n;j>=(x+1)*i;j--) //类似背包dp的方法减去第一部分
{
f[j]-=f[j-(x+1)*i];
f[j]=(f[j]%mod+mod)%mod;
}
}
for(int i=1,s=1;i<=2*n;i++) //前缀和的方式减去这一部分
{
f[i+n]-=s; s+=f[i];
f[i+n]=(f[i+n]%mod+mod)%mod;
if (s>=mod) s%=mod;
}
LL ans=0;
for(int i=1;i<=m;i++) //再尝试放不同的equipment来统计结果
{
int x; scanf("%d",&x);
ans+=f[2*n-x];
if (ans>=mod) ans%=mod;
}
printf("Case #%d: %I64d\n",++T_T,ans);
}
return 0;
}