hdu4666-曼哈顿距离最远点对(在线查询、删除、插入)

题意:m维空间,查询最远距离。n次删除和插入点操作,每次输出最远距离。

思路:模板题了。比赛的时候想到了打开绝对值,维护2^m个数据结构(支持插入、删除、求最值),map或者set。。。但是程序实现太弱了,以至于没敢认真的写写。还是得多写才行,有想法也不敢搞!

分析:考虑|a-b|+|c-d|,(a,c)到(b,d)的距离,绝对值打开以后,肯定为|p1 * a +p2*b + p3*c + p4*d|,其中p1\p2\p3\p4为1,或者-1。可以得出p1=p3,p2 = p4。

有这个结论,那维护2^m个数据结构即可。小证明,考虑a<=c && b<=d,那么,距离就是c-a + d - b,满足条件。且,该值一定为所有情况里的最大值。由绝对值三角不等式可证。

/*
map 真是好用啊!
*/

#include
#include
#include<string.h>
#include
#define N 60060
using namespace std;

map<int,int>mp[33];
typedef map<int,int>::iterator iter;
int seq[N][5];
int n ,m;


void del(int pos,int val){
    iter t1 = mp[pos].find(val);
    t1->second--;
    if (t1->second == 0)
        mp[pos].erase(t1);
    return ;
}

int mm;
int myabs(int x){
    return x<0?-x:x;
}
int get_ans(){
    int res = 0;
    for (int i=0;i){
        iter l = mp[i].begin();
        iter r = mp[i].end();
        r--;
        int tmp = myabs((l->first) - (r->first));
        if (tmp > res)
            res = tmp;
    }
    return res;
}
void dfs(int deep,int val,int root,int pos,int id){
    if (deep >= m){
        if (id == 0){
            mp[root][val]++;
        }else{
            del(root,val);
        }
        return ;
    }
    dfs(deep+1, val + seq[pos][deep],root*2,pos,id);
    dfs(deep+1, val - seq[pos][deep],root*2+1,pos,id);
    return ;
}
int main()
{
    while (scanf("%d%d",&n,&m)==2){
        mm = 1<<m;
        for (int i=0;i)
            mp[i].clear();

        for (int i=1;i<=n;i++){
            int id;
            scanf("%d",&id);
            if (id == 1){
                int pos;
                scanf("%d",&pos);
                dfs(0,0,0,pos,1);
            }else{
                for (int j=0;j)
                    scanf("%d",&seq[i][j]);
                dfs(0,0,0,i,0);
            }
          //  puts("d");
            printf("%d\n",get_ans());
        }
    }
    return 0;
}

 

转载于:https://www.cnblogs.com/wangsouc/articles/3258961.html

你可能感兴趣的:(hdu4666-曼哈顿距离最远点对(在线查询、删除、插入))