HDU 4666 Hyperspace(2013多校联合7 1001)

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


Hyperspace

Time Limit: 20000/10000 MS (Java/Others)    Memory Limit: 65535/65535 K (Java/Others)
Total Submission(s): 615    Accepted Submission(s): 280


Problem Description
The great Mr.Smith has invented a hyperspace particle generator. The device is very powerful. The device can generate a hyperspace. In the hyperspace, particle may appear and disappear randomly. At the same time a great amount of energy was generated.
However, the device is in test phase, often in a unstable state. Mr.Smith worried that it may cause an explosion while testing it. The energy of the device is related to the maximum manhattan distance among particle.
Particles may appear and disappear any time. Mr.Smith wants to know the maxmium manhattan distance among particles when particle appears or disappears.
 

Input
The input contains several test cases, terminated by EOF.
In each case: In the first line, there are two integer q(number of particle appear and disappear event, ≤60000) and k(dimensions of the hyperspace that the hyperspace the device generated, ≤5). Then follows q lines. In each line, the first integer ‘od’ represents the event: od = 0 means this is an appear
event. Then follows k integer(with absolute value less then 4 × 107). od = 1 means this is an disappear event. Follows a integer p represents the disappeared particle appeared in the pth event.
 

Output
Each test case should contains q lines. Each line contains a integer represents the maximum manhattan distance among paticles.


思路:这道题比赛时候是队友过的,赛后看了题解才明白过来。

详细的思路可以参考:09年集训队论文:《浅谈信息学竞赛中的“0”和“1”》

对于这道题,我们可以先从低维开始讨论,看看可以得出什么结论,

首先是一维的情况,显然我们只需维护一维空间点的最大值和最小值,然后相减即为所求答案,但这并没有对我们解决原题有太大帮助。

然后考虑二维的情况,对于二维空间中的两点A(x1,y1),B(x2,y2),它们的曼哈顿距离即为 |x1-x2|+|y1-y2|。

我们容易得出下面的结论:

|x1-x2|+|y1-y2|= MAX{ (x1-x2)+(y1-y2),(x1-x2)-(y1-y2),-(x1-x2)+(y1-y2),-(x1-x2)-(y1-y2) }

等价于|x1-x2|+|y1-y2|=MAX{ (x1+y1)-(x2+y2),(x1-y1)-(x2-y2),(-x1+y1)-(-x2+y2),(-x1-y1)-(-x2-y2)};

对于第二个式子,我们可以枚举二维空间中点的X轴和Y轴座标前的正负号,有2^2=4种可能,用0到3表示,我们不妨设1为正,0为负,则2(10)则表示x-y,1(01)表示 -x+y等等。。。我们可以用四个数据结构维护四种可能的点的最大值和最小值,然后做差取较大值即为答案。事实上,对于多维的情况我们也可以采用类似的方法做,只不过需要2^k种可能。题目中k最大为5,所以最多有32种情况。维护最大值和最小之可以用set,堆等等,考虑到还需要删除点,为了方便,我的代码中用的是 multiset,其实set和堆也是可行的。

参考代码如下:


#include <iostream>
#include <string.h>
#include <stdio.h>
#include <algorithm>
#include <set>
using namespace std;
multiset<int> ms[1<<5];
multiset<int>::iterator itor;
int a[60010][5];
int main()
{
    //freopen("dd.txt","r",stdin);
    int n,k;
    while(scanf("%d%d",&n,&k)!=EOF)
    {
        int i;
        for(i=0;i<32;i++)
        ms[i].clear();
        for(i=1;i<=n;i++)
        {
            int t;
            scanf("%d",&t);
            if(t==0)
            {
                for(int j=0;j<k;j++)
                scanf("%d",&a[i][j]);
                for(int j=0;j<1<<k;j++)
                {
                    int sum=0;
                    for(int tt=0;tt<k;tt++)
                    {
                        if(1&(j>>tt))
                        sum+=a[i][tt];
                        else
                        sum-=a[i][tt];
                    }
                    ms[j].insert(sum);
                }
            }
            else
            {
                int x;
                scanf("%d",&x);
                for(int j=0;j<(1<<k);j++)
                {
                    int sum=0;
                    for(int tt=0;tt<k;tt++)
                    {
                        if(1&(j>>tt))
                        sum+=a[x][tt];
                        else
                        sum-=a[x][tt];
                    }
                   itor=ms[j].find(sum);
                   ms[j].erase(itor);
                }
            }
            int ans=0;
            for(int j=0;j<(1<<k);j++)
            {
                itor=ms[j].end();
                itor--;
                int t1=(*itor);
                itor=ms[j].begin();
                int t2=(*itor);
                ans=max(ans,t1-t2);
            }
            printf("%d\n",ans);
        }
    }
    return 0;
}





發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章