Stars in Your Window (扫面线求 固定大小最大权值矩形

# 题意

给定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 }

 

posted @ 2020-03-20 00:35  Hyx'  阅读(134)  评论(0编辑  收藏  举报