SDUT 2608 第四届山东省ACM省赛 Alice and Bob (二进制 + 找规律)

传送门: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;
}


猜你喜欢

转载自blog.csdn.net/zuzhiang/article/details/80022766