NOIP2016普及组 第四题 题解

前面说过暴力的方法了,现在直接说说100分的。
首先我们根据题意,我们把1~n看成一个数轴,设CD为i,可以得出下图(自行理解):
  A    B       C   D
__|____|_______|___|____
       2*i      6*i+k       i
我们的主要目的就是把四重或者三重循环变为两重循环,所以就可以得出以下算法:
从上图可以看出,这一个数轴,两边间隔最大就是9*i+k,所以我们就可以枚举i为1到n div 9,然后就可以用一个前缀和去记录一下,对于每一个i,点A和B的组合一共有多少个(因为A和B在输入时都可能会出现多次),因为B最小是2*i,最大是n-7*i-1,所以我们可以把j设为B,枚举B的位置,利用乘法原理,可得前缀和:
S[j]:=s[j-1]+w[j]*w[j-2*i]  //w为每个数出现的次数,所以没出现过时,乘积也会为0。
而后缀和也同理。
算出前缀和,后缀和之后,就可以利用后缀和算对于现在枚举的i,算出A,得出B,而A的位置如图可得,就是1~n-7*i-1,而B的位置就显而易见,就是j+2*i,用另外三个乘起来就可得出方案数,累加答案就是
a[j,1]:=a[j,1]+s[k+6*i+1]*w[k];  //a[j,1]表示j这个数在被用作第一个魔法物品的次数,其他的以此类推
a[k,2]:=a[k,2]+s[k+6*i+1]*w[j];
而利用前缀和,去求出C和D的答案也同理。

你可能感兴趣的:(NOIP2016普及组 第四题 题解)