[BZOJ3028]食物

题目大意

你可以按照以下方式选择物品

A:偶数个

B:0个或1个

C:0个,1个或2个

D:奇数个

E:4的倍数个

F:0个,1个,2个或3个

G:不超过一个

H:3的倍数个

求使得选择物品的数量总和为\(N\)的方案数,并对\(10007\)取模

\(N<=10^{500}\)

解题思路

数据范围要求\(O(1)\)解法,这意味着要推式子!

生成函数裸题

我们将每一种物品的生成函数写出来

\[ A:1+x^2+x^4+\cdots=\frac{1}{1-x^2} \]

\[ B:1+x \]

\[ C:1+x+x^2 \]

\[ D:x+x^3+x^5+\cdots=\frac{x}{1-x^2} \]

\[ E:1+x^4+x^8+...=\frac{1}{1-x^4} \]

\[ F:1+x+x^2+x^3 \]

\[ G:1+x \]

\[ H:1+x^3+x^6+\cdots=\frac{1}{1-x^3} \]

乘积为

\[ \frac{x}{(1-x)^4} \]

我们的答案就是上面的式子化成无穷幂级数的N次方系数

继续推

\[ \begin{align} \frac{x}{(1-x)^4}&=x(1-x)^{-4} \\ &=x\sum_{i=0}^{\infty}{C_{-4}^{n}(-x)^{i}} \end{align} \]

其N次项系数为

\[ \begin{align} (-1)^{n-1}C_{-4}^{n-1}&=(-1)^{n-1}(-1)^{n-1}C_{n+2}^{n-1} \\ &=C_{n+2}^{n-1} \\ &=C_{n+2}^{3} \\ \end{align}\]

最后答案就是\(C_{n+2}^{3}\)

最后还剩下一个读入问题

我们发现\(C_{n+2}^{3}=\frac{(n+2)(n+1)n}{6}\)

只要像快速读入一样按位读,边读边模

最后除以6只要乘6的逆元就完成了

#include<iostream>
#include<cstdio>

const int inv=1668;
const int P=10007;

long long n;

void read(long long &n){
    char ch;
    while (isspace(ch=getchar()));
    n=ch&15;
    while (isdigit(ch=getchar())){n=(n<<1)+(n<<3)+(ch&15);n%=P;}
}

int main(){
    read(n);
    printf("%lld",(n+2)*(n+1)%P*n%P*inv%P);
}

猜你喜欢

转载自www.cnblogs.com/ytxytx/p/9486637.html