キャンディーとN人の子供 / Children and Candies(AtCoder-2021)

Problem Description

12:17 (UTC): The sample input 1 and 2 were swapped. The error is now fixed. We are very sorry for your inconvenience.

There are N children in AtCoder Kindergarten, conveniently numbered 1 through N. Mr. Evi will distribute C indistinguishable candies to the children.

If child i is given a candies, the child's happiness will become xia, where xi is the child's excitement level. The activity level of the kindergarten is the product of the happiness of all the N children.

For each possible way to distribute C candies to the children by giving zero or more candies to each child, calculate the activity level of the kindergarten. Then, calculate the sum over all possible way to distribute C candies. This sum can be seen as a function of the children's excitement levels x1,..,xN, thus we call it f(x1,..,xN).

You are given integers Ai,Bi(1≦i≦N). Find \sum_{x_1=A_1}^{B_1}\sum_{x_2=A_2}^{B_2}...\sum_{x_n=A_n}^{B_n}f(x_1,x_2,...,x_n) modulo 109+7.

Constraints

1≦N≦400
1≦C≦400
1≦Ai≦Bi≦400(1≦i≦N)

Partial Score

400 points will be awarded for passing the test set satisfying Ai=Bi(1≦i≦N).

Input

The input is given from Standard Input in the following format:

N C
A1 A2 ... AN
B1 B2 ... BN

Output

Print the value of \sum_{x_1=A_1}^{B_1}\sum_{x_2=A_2}^{B_2}...\sum_{x_n=A_n}^{B_n}f(x_1,x_2,...,x_n) modulo 109+7.

Example

Sample Input 1

2 3
1 1
1 1

Sample Output 1

4
This case is included in the test set for the partial score, since Ai=Bi. We only have to consider the sum of the activity level of the kindergarten where the excitement level of both child 1 and child 2 are 1 (f(1,1)).

If child 1 is given 0 candy, and child 2 is given 3 candies, the activity level of the kindergarten is 1^0*1^3=1.
If child 1 is given 1 candy, and child 2 is given 2 candies, the activity level of the kindergarten is 1^1*1^2=1.
If child 1 is given 2 candies, and child 2 is given 1 candy, the activity level of the kindergarten is 1^2*1^1=1.
If child 1 is given 3 candies, and child 2 is given 0 candy, the activity level of the kindergarten is 1^3*1^0=1.
Thus, f(1,1)=1+1+1+1=4, and the sum over all f is also 4.

Sample Input 2

1 2
1
3

Sample Output 2

14
Since there is only one child, child 1's happiness itself will be the activity level of the kindergarten. Since the only possible way to distribute 2 candies is to give both candies to child 1, the activity level in this case will become the value of f.

When the excitement level of child 1 is 1, f(1)=1^2=1.
When the excitement level of child 1 is 2, f(2)=2^2=4.
When the excitement level of child 1 is 3, f(3)=3^2=9.
Thus, the answer is 1+4+9=14.

Sample Input 3

2 3
1 1
2 2

Sample Output 3

66
Since it can be seen that f(1,1)=4,f(1,2)=15,f(2,1)=15,f(2,2)=32, the answer is 4+15+15+32=66.

Sample Input 4

4 8
3 1 4 1
3 1 4 1

Sample Output 4

421749
This case is included in the test set for the partial score.

Sample Input 5

3 100
7 6 5
9 9 9

Sample Output 5

139123417

题意:有 n 个人,c 个糖,第 i 个人得到 a 颗糖其愉悦度为 x_i^a ,整体的活跃度定义为 n 个人的活跃度的乘积,f(x1,x2,...,xn) 为所有分糖方案的对应的总活跃度,给出 Ai、Bi 为 xi 的范围,求  \sum_{x_1=A_1}^{B_1}\sum_{x_2=A_2}^{B_2}...\sum_{x_n=A_n}^{B_n}f(x_1,x_2,...,x_n),结果对 1E9+7取模

思路:

设 dp[i][j] 表示前 i 个人分 j 个糖的方案,那么当第 i 个分到 j 个糖时,前面的 i-1 个人就会分到 j-k 个糖,同时再乘以一个累加和 temp

即:dp[i][j]+=dp[i-1][j-k]*temp

temp 即为前面的 \sum_{x_1=A_1}^{B_1}\sum_{x_2=A_2}^{B_2}...\sum_{x_n=A_n}^{B_n} ,考虑时间复杂度,可以对其进行预处理优化,用 pow[i][j] 表示 i 的 j 次方,再用 sum[i][j] 表示前 i 个数 j 次方的前缀和,那么每次的 temp=sum[b[i]][k]-sum[a[i]-1][k]

同时,记得每一步都利用同余定理进行取模,于是最后的答案就是 dp[n][c]

Source Program

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<string>
#include<cstring>
#include<cmath>
#include<ctime>
#include<algorithm>
#include<utility>
#include<stack>
#include<queue>
#include<vector>
#include<set>
#include<map>
#define EPS 1e-9
#define PI acos(-1.0)
#define INF 0x3f3f3f3f
#define LL long long
const int MOD = 1E9+7;
const int N = 500+5;
const int dx[] = {0,0,-1,1,-1,-1,1,1};
const int dy[] = {-1,1,0,0,-1,1,-1,1};
using namespace std;
LL a[N],b[N];
LL power[N][N];//power[i][j]为i的j次方
LL sum[N][N];//sum[i][j]为前i个数j次方的前缀和
LL dp[N][N];//dp[i][j]为前i个人分了j个糖
int main(){
    int n,c;
    scanf("%d%d",&n,&c);
    for(int i=1;i<=n;i++)
        scanf("%lld",&a[i]);
    for(int i=1;i<=n;i++)
        scanf("%lld",&b[i]);

    for(int i=1;i<=500;i++){
        power[i][0]=1;
        for(int j=1;j<=500;j++)
            power[i][j]=(power[i][j-1]*i)%MOD;

    }
    for(int i=1;i<=500;i++)
        for(int j=0;j<=500;j++)
            sum[i][j]=(sum[i][j]+sum[i-1][j]+power[i][j])%MOD;

    dp[0][0]=1;
    for(int i=1;i<=n;i++){//枚举1-n个人
        for(int j=0;j<=c;j++){//枚举0-c个糖
            for(int k=0;k<=j;k++){
                LL temp=(sum[b[i]][k]-sum[a[i]-1][k]+MOD)%MOD;
                dp[i][j]=(dp[i][j]+dp[i-1][j-k]*temp)%MOD;
            }
        }
    }
    printf("%lld\n",dp[n][c]);

    return 0;
}

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值