题目:
题解:
我们再根据题目列出柿子
(1+x+x2+x3+...+xm1)(1+x+x2+x3+...+xm2)...
(
1
+
x
+
x
2
+
x
3
+
.
.
.
+
x
m
1
)
(
1
+
x
+
x
2
+
x
3
+
.
.
.
+
x
m
2
)
.
.
.
然后画一下柿子
后面的因为n不大可以暴力展开,那么我们现在有一个初步的x^n的系数,然而可以发现这个系数不是1就是-1要不就没有
这个区间的查询可以套路的转化为F(b)-F(a-1),那么F(i)表示吃不超过i个糖果的方案数
设p(k)表示指数为k的系数,那么
F(m)=∑k>=0(pk∗∑m−ki=0C(i+n−1,n−1))
F
(
m
)
=
∑
k
>=
0
(
p
k
∗
∑
i
=
0
m
−
k
C
(
i
+
n
−
1
,
n
−
1
)
)
好丑啊,画的好看一点吧
根据 C(i,j)=C(i−1,j−1)+C(i−1,j) C ( i , j ) = C ( i − 1 , j − 1 ) + C ( i − 1 , j ) ,上式又可以化简
完结撒花
诶等等还有一个问题,这个模数并不是个质数,在求组合数的时候可能没有逆元怎么办,可以发现模数不大,那我们每次%(mod*n!),然后在最后/n!就好了
代码:
#include <cstdio>
#include <iostream>
#define LL long long
using namespace std;
const int mod=2004;
int n,v[20],njc,ans;
int C(int n,int m)
{
if (m>n) return 0;
LL ans=1,now=(LL)njc*mod;
for (int i=n-m+1;i<=n;i++) ans=(LL)i%now*ans%now;
return ans/njc%mod;
}
void dfs(int t,int xi,int k,int m)
{
if (t>n)
{
ans=(ans+xi*C(n+m-k,n))%mod;
return;
}
dfs(t+1,xi,k,m);
dfs(t+1,-xi,k+v[t]+1,m);
}
int work(int x)
{
ans=0;dfs(1,1,0,x);
return ans;
}
int main()
{
int A,B;scanf("%d%d%d",&n,&A,&B);int sum=0;
for (int i=1;i<=n;i++) scanf("%d",&v[i]);
njc=1;for (int i=2;i<=n;i++) njc=njc*i;
printf("%d",((work(B)-work(A-1))%mod+mod)%mod);
}