275. 魔法阵

题目描述

六十年一次的魔法战争就要开始了,lester准备从附近的魔法场中汲取魔法能量。lester有m个魔法物品,编号分别为1,2,...,m。每个物品具有一个魔法值,我们用Xi表示编号为i的物品的魔法值。每个魔法值Xi是不超过n的正整数,可能有多个物品的魔法值相同。lester认为,当且仅当四个编号为a,b,c,d的魔法物品满足xa<xb<xc<xd,Xb-Xa=2(Xd-Xc),并且xb-xa<(xc-xb)/3时,这四个魔法物品形成了一个魔法阵,他称这四个魔法物品分别为这个魔法阵的A物品,B物品,C物品,D物品 现在,lester想要知道,对于每个魔法物品,作为某个魔法阵的A物品出现的次数,作为B物品的次数,作为C物品的次数,和作为D物品的次数

输入输出格式

输入格式

第一行包含两个空格隔开的正整数n和m。接下来m行,每行一个正整数,第i+1行的正整数表示Xi,即编号为i的物品的魔法值。n<=15000, m<=40000,Xi<=n。每个Xi是分别在合法范围内等概率随机生成的

输出格式

输出m行,每行四个整数。第i行的四个整数依次表示编号为i的物品作 为A,B,C,D物品分别出现的次数
保证标准输出中的每个数都不会超过10^9
每行相邻的两个数之间用恰好一个空格隔开

输入输出样例

输入样例#1:复 制

30 8
1
24
7
28
5
29
26
24

输出样例#1:复 制

4 0 0 0
0 0 1 0
0 2 0 0
0 0 1 1
1 3 0 0
0 0 0 2
0 0 2 2
0 0 1 0

 0.55分做法:从第1个约束条件可得所有可行答案都是单调递增的,所以可以排序一遍,减少枚举量,可以拿到55分。 1.正解: 首先可以发现每个x都小于n, 而n最大值只是15000, 所以可以开一个桶来存每个魔法值出现的次数。 回忆一下3个约束条件: xa<xb<xc<xd, xb-xa=2(xd-xc), xb-xa<(xc-xb)/3。现在改一下这3个式子。设t=xd-xc, 所以第2个式子可改成xb-xa=2t, 代入第3个式子, 2t<(xc-xb)/3, 移项变成6t<xc-xb, 设6t+k=xc-xb,能得到A的最小值为1, D的最大值为n, D-A=9t+k。 2.所以枚举t, 用t来表示各个魔法值的值, 易得t的范围是1≤t≤(n-1)/9在代码中为避免除法就写成t*9<n, 再枚举D, C的值可以算出, C=D-t,又因为使A,B,C,D满足条件的k的最小值是可以直接算出来的, 所以对于当前的C和D,最大A和B为A=D-9t-1,B=D-7t-1 3.如果A和B更小, 在其他条件不变的情况下, 只要C和B满足xc-xb>6t, 那么这个魔法阵就一定成立, 所以当a1<a2,b1<b2时,只要a2和b2能够和C,D组成魔法阵, a1和b1也一定能和C和D组成魔法阵, 可以使用前缀和优化。 然后又由乘法原理可得, 当前魔法值作为D物品的个数为SumD=SumA*SumB*SumC, 用前缀和优化SumA*SumB, C的情况可以顺便在算D的时候算出来。 4.因为要统计前缀和, 所以一定要顺推下去, 易知D最大值为n, 最小值为9*t+2, 再小就无法组成魔法阵。 同理可以枚举A, 但这个情况与D的情况有点不同, 在其他条件不变的情况下, 只要C和B满足xc-xb>6t, 那么这个魔法阵就一定成立, 所以当c1<c2,d1<d2时, 只要c1和d1能够与A和B组成魔法阵, c2和d2也一定能与A和B组成魔法阵, 可以使用后缀和优化。 因为需要统计后缀和, 所以需要逆推。枚举范围: A最大值为n-9t-1,最小值为1。 所以就可以算出每个魔法值作为A,B,C,D物品的次数了。输出时直接输出当前魔法物品的魔法值的次数即可。时间复杂度O(n)

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 2
    评论
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值