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;
}





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