传送门:SDUT 2608
题目大意:
给你一个多项式 (a0*x^(2^0)+1) * (a1 * x^(2^1)+1)*.......*(an-1 * x^(2^(n-1))+1),让你计算 x 的指数为 P 的前面的系数是多少。
思路:
题目其实不难,别被复杂的式子吓到。碰到这种感觉复杂的,就尽可能的根据自己已知的东西把前几项写出来找规律。
开始的时候我以为 x^P 前的系数会是多项 x^P 相加的结果,但是写出前 3 项后发现从 x^1 到 x^(2^n -1) 都是只有一项。
我们知道 P 一定可以拆解为多个二进制数相加的结果: P = 2^b[0] + 2^b[1] + …… +2^b[k],而 x^P 前面的系数正好是 a[b[0]]、a[b[1]]、……、a[b[k]] 的乘积值。所以规律也就找到了。
注意:
1.P的范围比较大,要用 long long,在山理工提交建议用 %lld,用 %I64d 有时候会出错。
2.如果所求的 P 过大,则结果为 0,但是代码中 x 下标对应 a[x] 的值可能不存在,所以将 a数组初始化为 0.
代码:
#include<stdio.h> #include<string.h> typedef long long LL; int main() { LL i,t,n,q,p,ans,a[60]; scanf("%lld",&t); while(t--) { scanf("%lld",&n); //将 a初始化为 0 的原因是如果所求的 x^p 中的p过大,则乘以 0后会使结果为 0 memset(a,0,sizeof(a)); for(i=0;i<n;i++) scanf("%lld",&a[i]); scanf("%lld",&q); while(q--) { scanf("%lld",&p); ans=1; LL x=0; while(p) { //将 p 分解为多个 2^b[i] 相加的结果,系数则为 a[b[i]]的乘积 if(p&1) ans=(ans*a[x])%2012; x++; p>>=1; } printf("%lld\n",ans); } } return 0; }