题目大意
你可以按照以下方式选择物品
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);
}