P1502 窗口的星星(扫描线)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P1502 窗口的星星(扫描线)相关的知识,希望对你有一定的参考价值。
P1502 窗口的星星(扫描线)
给定矩形宽高,每个点有个点权,最大覆盖点券权和。
显然扫描线。
因为不包括边界,上右都减1.
对每个点建立边权(x,y,y+h-1,l),(x+w-1,y,y+h-1,-l)
然后对x排序,x相同优先大权,用线段树维护y。每次区间更新,维护答案即可。
注意离散化。
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=2e4+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
const int hashmod[4] = {402653189,805306457,1610612741,998244353};
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define PLL pair<ll,ll>
#define x first
#define y second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define rep(i,a,b) for(int i=a;i<=b;++i)
#define per(i,a,b) for(int i=a;i>=b;--i)
#define ios ios::sync_with_stdio(false),cin.tie(nullptr)
void Print(int *a,int n){
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
}
//区间修改 区间求和
#define il inline
#define lx x<<1
#define rx x<<1|1
#define len(x) (a[x].r-a[x].l+1)
struct SegTree{
struct node{
int l,r;
int lz;
ll s;
}a[N<<2];
il void re(int x){ a[x].s=max(a[lx].s,a[rx].s); }
il void ptg(int x,int y){
a[x].lz+=y;
a[x].s+=y;
}
il void pd(int x){
if(a[x].lz){
ptg(lx,a[x].lz),ptg(rx,a[x].lz);
a[x].lz=0;
}
}
il void bud(int x,int l,int r){
a[x].l=l,a[x].r=r;
a[x].lz=a[x].s=0;
if(l==r){
//scanf("%d",&a[x].s);
return;
}
int m=(l+r)>>1;bud(lx,l,m),bud(rx,m+1,r);
re(x);
}
il void upd(int x,int l,int r,ll val){
if(a[x].l>=l&&a[x].r<=r){
ptg(x,val);return;
}
pd(x);
int m=(a[x].l+a[x].r)>>1;
if(l<=m) upd(lx,l,r,val);
if(r>m) upd(rx,l,r,val);
re(x);
}
il ll que(int x,int l,int r){
if(a[x].l>=l&&a[x].r<=r) return a[x].s;
pd(x);
int m=(a[x].l+a[x].r)>>1;ll ans=0;
if(l<=m) ans+=que(lx,l,r);
if(r>m) ans+=que(rx,l,r);
return ans;
}
}T;
struct node{
int x,y,v;
bool operator<(const node &a)const{
return x==a.x?v>a.v:x<a.x;
}
}a[N];
ll b[N];
int main(){
int t;
scanf("%d",&t);
while(t--){
int n,W,H;
scanf("%d%d%d",&n,&W,&H);
int cnt=0;
rep(i,1,n){
int j=(i<<1)-1;
scanf("%d%d%d",&a[j].x,&a[j].y,&a[j].v);
a[j+1]=a[j];
a[j+1].x+=W-1;
a[j+1].v=-a[j].v;
b[++cnt]=a[j].y,b[++cnt]=a[j].y+H-1;
}
n<<=1;
sort(a+1,a+n+1);
sort(b+1,b+n+1);
int m=unique(b+1,b+n+1)-b-1;
T.bud(1,1,m);
ll ans=0;
rep(i,1,n){
int y1=lower_bound(b+1,b+m+1,a[i].y)-b;
int y2=lower_bound(b+1,b+m+1,a[i].y+H-1)-b;
T.upd(1,y1,y2,a[i].v);
ans=max(ans,T.a[1].s);
}
printf("%lld\\n",ans);
}
return 0;
}
以上是关于P1502 窗口的星星(扫描线)的主要内容,如果未能解决你的问题,请参考以下文章