一道题含了好多知识点。。
首先母函数不多说看式子。
π(1+x+x^1+x^2+...+x^mi)=π{[1-x^(mi+1)]/[1-x]}=(1-x)^(-n) * π(1-x^(mi+1))=(1+x+x^2+...+x^inf..)^n * π(1-x^(mi+1));
然后答案是f(b)-f(a-1) ,f(m) 表示0到m的系数和
那么后面的π(1-x^(mi+1))可以暴力拆出来,最多2^n项,
然后枚举每一项,枚举到 ax^b, 这项 对f(m)的贡献就是(1+x+x^2+...+x^inf..)^n 的 0~m-b的系数和
即,C(0+n-1,n-1)+C(n,n-1)+C(n+1,n-1)+...+C(m-b+n-1,n-1),
然后因为C(i,i)+C(i+1,i)+...+C(k,i)=C(k+1,i+1);(杨辉三角) 那么上式就可以直接化成一个组合数
C(x,y)%2004 怎么求?
其实问题在于,给定x,y ,x是y的倍数,x很大,y比较小。求(x/y)%p (p也挺小的,但不一定和y互质)
设z=x/y ; 求出k=x%(py) → x=k+tpy; 因为y整除x,so y整除k, 且我们求出来的k是%py下的 ,gcd(py,y)==y; 所以最后%意义下的k依然是被y整除的。
k/y%p就是最后的 (x/y)%p
1 #include <bits/stdc++.h> 2 using namespace std; 3 const int mo=2004; 4 int n,m,L,R,k,t,w[15]; 5 struct term{ 6 int a,b; 7 }a[2000],b[2000]; 8 bool cmp(term a,term b){ return a.b<b.b; } 9 int gcd(int x,int y){ 10 return y?gcd(y,x%y):x; 11 } 12 int C(int x,int y){ 13 if (x<y) return 0; int z=1,d,u; 14 for (int i=2;i<=n;++i) w[i]=i; 15 for (int i=x-y+1;i<=x;++i){ //我用的不是上面那种求法 16 u=i; 17 for (int j=2;j<=n;++j) if (w[j]>1) d=gcd(u,w[j]),u/=d,w[j]/=d; 18 (z*=u%mo)%=mo; 19 } 20 return z; 21 } 22 int get(int m){ 23 int ans=0; 24 for (int i=1;i<=t;++i){ 25 ans+=C(m-a[i].b+n,n)*a[i].a%mo; 26 if (ans>=mo) ans-=mo; 27 } 28 return ans; 29 } 30 int main(){ 31 scanf("%d%d%d",&n,&L,&R); a[t=1]={1,0}; b[0].b=-1; 32 for (int i=1;i<=n;++i){ 33 scanf("%d",&m); k=0; 34 for (int i=1;i<=t;++i) b[i]=a[i]; 35 for (int i=1;i<=t;++i) b[i+t]={a[i].a?mo-a[i].a:0,m+1+a[i].b}; 36 sort(b+1,b+t+t+1,cmp); 37 for (int i=1;i<=t+t;++i){ 38 if (b[i].b>R) break; 39 if (b[i].b!=b[i-1].b) a[++k]={0,b[i].b}; 40 a[k].a+=b[i].a; if (a[k].a>=mo) a[k].a-=mo; 41 } 42 t=k; 43 } 44 printf("%d",(get(R)-get(L-1)+mo)%mo); 45 return 0; 46 }