二维坐标中一个移动矩形块中的最大和值

来源:互联网 发布:阿里云认证 有用吗 编辑:程序博客网 时间:2024/06/05 01:00

题意: 在一个二维坐标中有很多个点,每个点有个权值。

            给出一个矩形框的宽与高,移动该大小的框,

            把所有在框内的点的值加起来得到一个和,最该最大的和值。


数据有最多100000个点,


思路:把坐标点从下到上,从左到右排序。

            把横坐标的点记录一下,看有哪些点,并排序去重。

            loop:

                  加入每个点,更新这个点应该在横坐标上的值。

                  去掉纵坐标与当前点纵坐标距离过大的点

                  打最大值。



#include<stdio.h>#include<iostream>#include<math.h>#include<iostream>#include<algorithm>#include<map>#include<string.h>#include<queue>using namespace std;#define N 100100int n,W,H;struct my{int x,y,w;}go[N];int hi[N],len;struct tree{int left,right,mm,m;}t[4*N];int p[N];bool cmp(my a,my b){if (a.y!=b.y) return a.y<b.y;else return a.x<b.x;}map<int,int> ind;void build(int cur,int left,int right){t[cur].left=left;t[cur].right=right;t[cur].m=t[cur].mm=0;int m = (left+right)>>1;if (left!=right){build(cur<<1,left,m);build(cur<<1|1,m+1,right);}}void update(int cur,int left,int right,int v){if (left==t[cur].left && right==t[cur].right){t[cur].mm+=v;t[cur].m+=v;return;}int m=(t[cur].left+t[cur].right)>>1,L=cur<<1,R=cur<<1|1;if (t[cur].m!=0){t[L].m+=t[cur].m;t[R].m+=t[cur].m;t[L].mm+=t[cur].m;t[R].mm+=t[cur].m;t[cur].m=0;}if (right<=m) update(L,left,right,v);else if (left>m) update(R,left,right,v);else update(L,left,m,v),update(R,m+1,right,v);t[cur].mm=max(t[L].mm,t[R].mm);}int main(){freopen("in","r",stdin);    int i,j,k;    int x,y,w;    int ans=0;    cin>>n>>W>>H;    for (i=0;i<n;i++)    {    scanf("%d%d%d",&go[i].x,&go[i].y,&go[i].w);    }    sort(go,go+n,cmp);        for (i=0;i<n;i++) hi[i]=go[i].x;    sort(hi,hi+n);        for (len=i=1;i<n;i++) if (hi[i]!=hi[i-1]) hi[len++]=hi[i];    for (i=0;i<len;i++) ind[hi[i]]=i;    for (j=i=len-1;i>=0;--i)    {    while (j && hi[i]-hi[j-1]<W) j--;p[i]=j;     }    build(1,0,len-1);    for (i=j=0;i<n;i++)    {    update(1,p[ind[go[i].x]],ind[go[i].x],go[i].w);    while (j<i && go[i].y-go[j].y >= H) update(1,p[ind[go[j].x]],ind[go[j].x],-go[j].w),j++;    ans=max(ans,t[1].mm);    //cout<<t[2].mm<<' '<<t[2].m<<endl;    }      //  for (i=0;i<len;i++) cout<<p[i]<<' ';cout<<endl;    printf("%d\n",ans);    }


0 0
原创粉丝点击