题目:http://poj.org/problem?id=2482
大意:在一个坐标系中给你n(10^4)个点(点的坐标范围为0<=x,y<2^31),每个点有一个权值,然后给你一个长宽分别为w,h(10^6)的矩形(平行于坐标轴);
现在你的任务就是求出用这个矩形所覆盖的点的权值和的最大值(矩形边上的点不算)(矩形可以平移但是不能旋转)
思路:每个星星都可以以它自己为矩形的左下角(不能包括矩形边),那么就有n个矩形,就转化成了黑书上的第108页的题目,即统计所有1x1的小方格被覆盖的矩形最多的;
由于点的数量很小,但是坐标的范围很大,于是需要离散化;
自左向右扫描,左右竖线(在程序中用正负表示)标志矩形进入和退出阴影区域,利用线段树进行更新;
代码:
![](https://images.cnblogs.com/OutliningIndicators/ContractedBlock.gif)
1 #include <iostream> 2 #include<cstdio> 3 #include<cstring> 4 #include<algorithm> 5 using namespace std; 6 const int maxn=10010; 7 struct node 8 { 9 __int64 id;//坐标值 10 int flag;//标记左边还是右边 11 int xh;//序号 12 }sx[maxn*2],sy[maxn*2]; 13 struct bj 14 { 15 int y1,y2; 16 int val;//左进右出,左为正,有为负 17 }line[maxn*2]; 18 int n; 19 int tree[maxn*8]; 20 int lz[maxn*8];//懒惰标记 21 bool cmp(struct node a,struct node b) 22 { 23 if(a.id==b.id) 24 return a.flag>b.flag; 25 return a.id<b.id; 26 } 27 void disper()//离散化 28 { 29 sort(sx,sx+(n<<1),cmp); 30 sort(sy,sy+(n<<1),cmp); 31 int temp=sy[0].id; 32 int tg=1; 33 int i; 34 for(i=0;i<n*2;i++) 35 { 36 if(temp!=sy[i].id) 37 { 38 tg++; 39 temp=sy[i].id; 40 } 41 if(sy[i].flag) 42 { 43 line[sy[i].xh*2].y2=tg; 44 line[sy[i].xh*2+1].y2=tg; 45 } 46 else 47 { 48 line[sy[i].xh*2].y1=tg; 49 line[sy[i].xh*2+1].y1=tg; 50 } 51 } 52 } 53 void build(int l,int r,int w) 54 { 55 tree[w]=0; 56 lz[w]=0; 57 if(l==r) 58 { 59 return ; 60 } 61 int m=(l+r)>>1; 62 build(l,m,w<<1); 63 build(m+1,r,w<<1|1); 64 } 65 66 void update(int l,int r,int w,int L,int R,int val) 67 { 68 if(L<=l&&R>=r) 69 { 70 tree[w]+=val; 71 lz[w]+=val;//延迟标记 72 return ; 73 } 74 if(lz[w]!=0)//取消标记 75 { 76 lz[w<<1|1]+=lz[w]; 77 lz[w<<1]+=lz[w]; 78 tree[w<<1]+=lz[w]; 79 tree[w<<1|1]+=lz[w]; 80 lz[w]=0; 81 } 82 int m=(l+r)>>1; 83 if(L>m) 84 update(m+1,r,w<<1|1,L,R,val); 85 else if(R<=m) 86 update(l,m,w<<1,L,R,val); 87 else 88 { 89 update(l,m,w*2,L,m,val); 90 update(m+1,r,w<<1|1,m+1,R,val); 91 } 92 tree[w]=max(tree[w<<1],tree[w<<1|1]); 93 } 94 int main() 95 { 96 int w,h; 97 while(scanf("%d%d%d",&n,&w,&h)!=EOF) 98 { 99 int i; 100 __int64 x,y; 101 int valu; 102 for(i=0;i<n;i++) 103 { 104 scanf("%I64d%I64d%d",&x,&y,&valu); 105 sx[i<<1].id=x; 106 sx[i<<1].flag=0;//左边 107 sx[i<<1|1].id=x+w; 108 sx[i<<1|1].flag=1;//右边 109 sx[i<<1|1].xh=sx[i<<1].xh=i; 110 111 sy[i<<1].id=y; 112 sy[i<<1].flag=0; 113 sy[i<<1|1].id=y+h; 114 sy[i<<1|1].flag=1; 115 sy[i<<1|1].xh=sy[i<<1].xh=i; 116 117 line[i<<1].val=valu; 118 line[i<<1|1].val=-valu; 119 } 120 disper();//离散化 121 /*for(i=0;i<n*2;i++) 122 { 123 printf("%d %d %d ",line[i].yd,line[i].yu,line[i].val); 124 }*/ 125 n=n*2; 126 build(1,n,1); 127 128 int id; 129 int ans=0; 130 for(i=0;i<n;i++)//扫描 131 { 132 id=sx[i].xh*2+sx[i].flag; 133 line[id].y1++;//不包括边 134 update(1,n,1,line[id].y1,line[id].y2,line[id].val); 135 if(ans<tree[1]) 136 ans=tree[1]; 137 } 138 printf("%d ",ans); 139 } 140 return 0; 141 }