2013 多校第七场 hdu 4666 Hyperspace(最远曼哈顿距离)

题目:http://acm.hdu.edu.cn/showproblem.php?pid=4666

题目大意:n个操作,d个维度,0表示加点,1表示删点,次操作都要输出当前存在点的最长曼哈顿距离。

思路:贴一段别人博客上的一段话,比赛的时候就是看了这段话才A的,写的很好~~

求最远曼哈顿距离,对于一个n维的空间,其中两点的曼哈顿距离为:|x1-y1|+|x2-y2|+|x3-y3|+|x4-y4|+……+|xn-yn|      (两点的坐标分别为(x1,x2,……,xn)、(y1,y2,……,yn))

以下以二维平面为例研究:        

设距离最远的两点为i,j,可知所求的最大距离必定有以下四种形式之一:

(xi-xj)+(yi-yj), (xj-xi)+(yi-yj), (xi-xj)+(yj-yi), (xj-xi)+(yj-yi) 变形一下,把相同点的坐标放到一起,

即 (xi+yi)-(xj+yj), (-xi+yi)-(-xj+yj), (xi-yi)-(xj-yj), (-xi-yi)-(-xj-yj) 再变一下,把中间变成‘+',

即 (xi+yi)+(-xj-yj), (-xi+yi)+(xj-yj), (xi-yi)+(-xj+yj),(-xi-yi)+(xj+yj)

由此,可以发现一个规律,即去绝对值之后把同一点的坐标放在一起,对应坐标的符号总是相反的,如(-xi+yi)与(xj-yj)。

假如我们用0表示负号,1表示正号,则(-xi+yi)与(xj-yj)两个括号内的符号可以表示为:01和10       

当你多举几个例子之后,就会发现,对于一个确定的维数D,符号转化成的二进制数,它们的和总是一个定值,即2^d-1,        这就说明了,当我们知道了前一个点去绝对值之后的符号,就可以知道第二个点去绝对值后的符号是怎样的

于是只要对所有的点(xi,yi),依次计算出(xi+yi),(xi-yi),(-xi+yi),(-xi-yi)这四种形式,然后把每个点i算出来的这四种情况的最大值分别记录到一个数组max[]中,然后枚举每一种去绝对值的组合,组合后的最大值即为answer

再补充一点,这边是加,如果是减也一样,那就不是互补,而是相同,比如 i 点的符号是00,那么与之配对的 j 点坐标也应该是00。

代码如下:

#include<cstdio>
#include<cstring>
#include<queue>
#include<algorithm>
using namespace std;

const int MAXN = 61111;

struct Node
{
    int s,id;
    Node(){}
    Node(int a,int b) : s(a),id(b) {}
    bool operator < (const Node &tmp) const
    {
        return s<tmp.s;
    }
};

priority_queue <Node> q[1<<6];

int p[11];

int dis[MAXN];

int main()
{
    int n,d;
    while(~scanf("%d%d",&n,&d))
    {
        int od;
        int S = (1<<d) - 1;
        int ans = 0;
        memset(dis,0,sizeof(dis));
        for(int i = 0;i<=S;i++)
            while(!q[i].empty())
                q[i].pop();
        for(int i = 1;i<=n;i++)
        {
            scanf("%d",&od);
            if(od==0)
            {
                for(int j = 0;j<=S;j++)
                {
                    while(!q[j].empty()&&dis[q[j].top().id])
                    {
                        q[j].pop();
                    }
                }

                for(int j = 1;j<=d;j++)
                {
                    scanf("%d",&p[j]);
                }
                for(int j = 0;j<=S;j++)
                {
                    int ss = 0;
                    for(int k = 0;k<d;k++)
                    {
                        if(!(j&(1<<k)))
                        {
                            ss += -1*p[k+1];
                        }
                        else ss += p[k+1];
                    }
                    if(!q[S-j].empty())
                        ans = max(ans,ss + q[S-j].top().s);
                }
                for(int j = 0;j<=S;j++)
                {
                    int ss = 0 ;
                    for(int k = 0;k<d;k++)
                    {
                        if(!(j&(1<<k)))
                        {
                            ss += -1*p[k+1];
                        }
                        else ss += p[k+1];
                    }
                    q[j].push(Node(ss,i));
                }
            }
            else
            {
                int pos;
                scanf("%d",&pos);
                dis[pos] = 1;
                for(int j = 0;j<=S;j++)
                {
                    while(!q[j].empty()&&dis[q[j].top().id])
                    {
                        q[j].pop();
                    }
                }
                ans = 0 ;
                for(int j = 0;j<=S;j++)
                {
                    if(!q[S-j].empty()&&!q[j].empty())
                        ans = max(ans,q[j].top().s + q[S-j].top().s);
                }
            }
            printf("%d\n",ans);
        }
    }
    return 0;
}


你可能感兴趣的:(2013 多校第七场 hdu 4666 Hyperspace(最远曼哈顿距离))