歌名 - 歌手
0:00

    【NOIP2016普及组复赛】魔法阵

    题目

    这里写图片描述

    分析

    设xd-xc为i,那么xb-xa=2i,
    又因为xb-xa<(xc-xb)/3,
    那么c>6i+b。
    于是,先枚举i,
    再分别枚举xa和xd,
    根据之间的关系,用前缀和求出每一种魔法阵的每一种物品的次数。

    #include <cmath>
    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <algorithm>
    #include <queue>
    const int maxlongint=2147483647;
    const int mo=1000000007;
    const int N=50005;
    using namespace std;
    int n,m,val[N],w[N],a[N],b[N],c[N],d[N];
    int main()
    {
    	freopen("magic.in","r",stdin);
    	freopen("magic.out","w",stdout);
        scanf("%d%d",&n,&m);
        for(int i=1;i<=m;i++)
    	{
            scanf("%d",&val[i]);
            w[val[i]]++;
        }
        for(int i=1;i<=n/9;i++)
    	{
            int num=0;
            for(int xa=n-9*i-1;1<=xa;xa--)
    		{
    			int xd=xa+9*i+1,xc=xa+8*i+1,xb=xa+2*i;
                num+=w[xd]*w[xc];
                a[xa]+=w[xb]*num;
                b[xb]+=w[xa]*num;
            }
            num=0;
            for(int xd=9*i+2;xd<=n;xd++)
    		{
    			int xc=xd-i,xb=xd-7*i-1,xa=xd-9*i-1;
                num+=w[xa]*w[xb];
                d[xd]+=w[xc]*num;
                c[xc]+=w[xd]*num;
            }
        }
        for(int i=1;i<=m;i++)
            printf("%d %d %d %d\n",a[val[i]],b[val[i]],c[val[i]],d[val[i]]);
    }
    
    
    posted @ 2018-05-21 12:17  无尽的蓝黄  阅读(599)  评论(0编辑  收藏  举报