给定n个点和固定矩形宽w和高h,在平面坐标系中n个点表示为(x,y,c)表示在x,y点的权值为c,
求出矩形中包含点的最大权值(其中矩形边上的点不计入权值
# 题解
因为不能包含边界的所以所有给定的点的左边-0.5即可,左下角为(x,y),右上角为(x+w-1,y+h-1)
将每个星星看作一个固定的矩形,这个固定的矩形的权值就是点的权值,求出相交的矩形权值的最大值
每个点形成两个四元组(x,y,y+h-1,c) 和 (x+w,y,y+h-1,-c),将这些四元组按照横坐标排序,
如果x相等的两个点需要先加上新的再减去旧的所以将c作第二关键字排序
1)坐标范围大先离散化
2)二分找离散化后的坐标
3)对y轴建立线段树,线段树中存的是线段所以要-1
以此将分好的矩形按照x点加入线段树即可,需要pushup当前值到根,
每次加都保存最大值,最后即答案
1 #include <bits/stdc++.h> 2 using namespace std; 3 typedef long long ll; 4 const int N=1e4+10; 5 long long n,w,h; 6 struct segment{ 7 long long x,y1,y2,c; 8 bool operator <(const segment &t) const { 9 if(x==t.x) 10 return c<t.c; 11 return x<t.x; 12 } 13 }seg[N*2]; 14 struct node { 15 int l,r; 16 long long val,add; 17 }tr[N*8]; 18 vector<long long>ys; 19 int find(ll y){ 20 return lower_bound(ys.begin(),ys.end(),y)-ys.begin(); 21 } 22 void pushup(int u){ 23 tr[u].val=max(tr[u<<1].val,tr[u<<1|1].val); 24 } 25 void pushdown(int u){ 26 if(tr[u].add){ 27 int add=tr[u].add; 28 tr[u<<1].val+=add,tr[u<<1|1].val+=add; 29 tr[u<<1].add+=add;tr[u<<1|1].add+=add; 30 tr[u].add=0; 31 } 32 } 33 void build(int u,int l,int r){ 34 tr[u]={l,r,0,0}; 35 if(l!=r){ 36 int mid= l + r >>1; 37 build(u<<1,l,mid); 38 build(u<<1|1,mid+1,r); 39 } 40 } 41 void change(int u,ll l,ll r,ll v){ 42 if(tr[u].l>=l && tr[u].r<=r){ 43 tr[u].add+=v; 44 tr[u].val+=v; 45 } 46 else { 47 pushdown(u); 48 int mid=tr[u].l+tr[u].r>>1; 49 if(l<=mid) change(u<<1,l,r,v); 50 if(r>mid) change(u<<1|1,l,r,v); 51 pushup(u); 52 } 53 } 54 int main(){ 55 while(cin>>n>>w>>h){ 56 for(int i=0,j=0;i<n;i++){ 57 long long x,y,c; 58 cin>>x>>y>>c; 59 seg[j++]={x,y,y+h-1,c}; 60 seg[j++]={x+w,y,y+h-1,-c}; 61 ys.push_back(y); 62 ys.push_back(y+h-1); 63 } 64 sort(ys.begin(),ys.end()); 65 ys.erase(unique(ys.begin(),ys.end()),ys.end()); 66 sort(seg,seg+2*n); 67 build(1,0,ys.size()-1); 68 long long ans=0; 69 for(int i=0;i<n*2;i++){ 70 long long y1=find(seg[i].y1),y2=find(seg[i].y2),c=seg[i].c; 71 change(1,y1,y2,c); 72 ans=max(ans,tr[1].val); 73 } 74 cout<<ans<<endl; 75 } 76 }