NOIP2017普及——t4 魔法阵

#include
using namespace std;
int v[40005];
int w[40050];
int a[40005],b[40005],c[40005],d[40005];
//a[x[i]]	第i个魔法品的坐标(其实是魔法值,但是我们抽象成数轴)作为a物品的次数  
int n,m;
int main()
{
	cin>>n>>m;
	for(int i=1;i<=m;i++)
	{
		cin>>v[i];
		w[v[i]]++;
	}
	
	for(int i=1;i<=n/9;i++)	//dis(c,d)
	{
		int p=i*9+1,sum=0;	//p=dis(a,d)->这里指一个差;
							//sum:方案总数 
		for(int j=i*9+2;j<=n;j++)	//d的坐标
		{
			//j-p:a坐标
			//j-p+2*i b坐标 
			//w[j-p]->相当于a的坐标的数量(相同魔法值的个数)  
			//w[j-p+2*i]->相当于b的坐标的数量(相同魔法值的个数)
			//i*2=xb-xa 
			sum+=w[j-p]*w[j-p+2*i];
			//乘法原理
			//j-i:c的坐标
			d[j]+=w[j-i]*sum;
			//以j(d)为坐标 作为d出现的次数 
			c[j-i]+=w[j]*sum; 
			//以j-i(c)为坐标 作为c出现的次数 
			
			
			//对乘法原理的运用  sum为a,b搭配起来的总数量,于是可以推出这个时候d可以的方案总数以及c 
		}
		p=i*8+1,sum=0;
		for(int j=n-(i*9+1);j;j--)	//a的坐标,可以想象一下,a的坐标范围在1~n-(i*9+1)---此时d点在数轴的最右端,dis(b,c)是3*i+1 
		{
			sum+=w[j+p]*w[j+p+i];	//tot-c,tot-d
			a[j]+=w[j+i*2]*sum;
			b[j+i*2]+=w[j]*sum;
		} 
	}
	for(int i=1;i<=m;i++)
	{
		cout<

建议先了解一下大概思路 然后直接看注释 (图片来自洛谷的题解(ID:frankchenfu))

NOIP2017普及——t4 魔法阵_第1张图片

你可能感兴趣的:(NOIP2017普及——t4 魔法阵)