题目:https://www.acwing.com/problem/content/250/
题意:给你n个点,现在问你能每个点都有个权值,问你能覆盖最多的权值是多少,边界不算
思路:这个其实和我之前有篇博客思路一样,那个是只用求覆盖最多的点是什么,我们也只要建扫描线,因为我们可以把每个点看作成一个区域,然后代表在这个区域内可以覆盖到这个点,这个题的话只要把扫描线原先那个入边出边的权值改成点的权值即可,然后判边界问题
https://www.cnblogs.com/Lis-/p/11279390.html
#include <bits/stdc++.h> using namespace std; const int N=2e4+10;//要2*n,切记切记,我就是因为这个恶心的锅,坑害了一个半小时. #define int long long//注意 #define lson l,(l+r)/2,p<<1 #define rson (l+r)/2,r,p<<1|1 int n,w,h,ys[N]; struct line_tree { int l,r,len,lazy;//开了懒惰标记,也就是延迟标记 #define l(x) x<<1 #define r(x) (x<<1)+1 #define m(x) (t[x].l+t[x].r)>>1 } t[N<<2]; struct node { int x,y1,y2,f; } p[N]; int cmp(node a,node b) { return a.x<b.x || (a.x==b.x && a.f<0);//排序特殊点 } inline void push_up(int p) { t[p].len=max(t[l(p)].len,t[r(p)].len)+t[p].lazy; } inline void build(int l,int r,int p) { t[p].l=ys[l]; t[p].r=ys[r]; t[p].lazy=0; t[p].len=0; if (r-l==1) return ; int mid=(l+r)>>1; build(lson); build(rson); push_up(p); } inline void change(int l,int r,int k,int p) { if (t[p].l>=l && t[p].r<=r) { t[p].lazy+=k; t[p].len+=k; return ; } if (l<t[l(p)].r) change(l,min(r,t[l(p)].r),k,l(p)); if (r>t[r(p)].l) change(max(l,t[r(p)].l),r,k,r(p)); push_up(p); } inline void init() { while(scanf("%lld%lld%lld",&n,&w,&h)!=EOF) { int cnt=0,num=1; for(int i=1; i<=n; i++) { int xx,yy,k; scanf("%lld%lld%lld",&xx,&yy,&k) ; p[cnt].x=xx; p[cnt].y1=yy; p[cnt].y2=yy+h; p[cnt++].f=k; p[cnt].x=xx+w; p[cnt].y1=yy; p[cnt].y2=yy+h; p[cnt++].f=-k; ys[num++]=yy; ys[num++]=yy+h; } sort(ys+1,ys+num); int ans=0; num=unique(ys+1,ys+num)-(ys+1); sort(p,p+cnt,cmp); build(1,num,1); for(int i=0; i<cnt; i++) { change(p[i].y1,p[i].y2,p[i].f,1); if(p[i].f>0) ans=max(ans,t[1].len); } printf("%lld\n",ans); } } signed main() { // freopen("stdin.in","r",stdin); // freopen("stdout.out","w",stdout); init(); return 0; }