窗口的星星
题目背景
小卡买到了一套新房子,他十分的高兴,在房间里转来转去。
题目描述
晚上,小卡从阳台望出去,“哇~~~~好多星星啊”,但他还没给其他房间设一个窗户。
天真的小卡总是希望能够在晚上能看到最多最亮的星星,但是窗子的大小是固定的,边也必须和地面平行。
这时小卡使用了超能力(透视术)知道了墙后面每个星星的位置和亮度,但是小卡发动超能力后就很疲劳,只好拜托你告诉他最多能够有总和多亮的星星能出现在窗口上。
输入格式
本题有多组数据,第一行为 T T T,表示有 T T T 组数据。
对于每组数据:
第一行 3 3 3 个整数 n , W , H n,W,H n,W,H 表示有 n n n 颗星星,窗口宽为 W W W,高为 H H H。
接下来 n n n 行,每行三个整数 x i , y i , l i x_i,y_i,l_i xi,yi,li 表示星星的坐标在 ( x i , y i ) (x_i,y_i) (xi,yi),亮度为 l i l_i li。
输出格式
T T T 个整数,表示每组数据中窗口星星亮度总和的最大值。
样例 #1
样例输入 #1
2
3 5 4
1 2 3
2 3 2
6 3 1
3 5 4
1 2 3
2 3 2
5 3 1
样例输出 #1
5
6
提示
小卡买的窗户框是金属做的,所以在边框上的不算在内。
数据范围
1
≤
T
≤
10
1\le T \le 10
1≤T≤10
1
≤
n
≤
1
0
4
1\le n \le 10^4
1≤n≤104
1
≤
W
,
H
≤
1
0
6
1\le W,H \le 10^6
1≤W,H≤106
0
≤
x
i
,
y
i
<
2
31
0\le x_i,y_i < 2^{31}
0≤xi,yi<231
题目分析
线段树+去离散化
AC Code
#include<bits/stdc++.h>
using namespace std;
#define FOR(i,start,end) for(int i=start;i<=end;i++)
#define ROF(i,start,end) for(int i=start;i>=end;i--)
#define EPS 1e-8
#define INF 0x3f3f3f3f
#define mm0(x) memset(x,0,sizeof(x))
#define mm_1(x) memset(x,-1,sizeof(x))
#define mm3f(x) memset(x,0x3f,sizeof(x))
#define db1(a) cout<<#a<<"="<<a<<endl
#define db2(a,i) cout<<#a<<"["<<i<<"]="<<a[i]<<endl
#define db3(a,i,j) cout<<#a<<"["<<i<<"]["<<j<<"]="<<a[i][j]<<endl
typedef long long ll;
typedef pair<int,int> pii;
// begin code
int T,n,W,H;
const int N=1e5+5;
struct node {
int tag;
int val;
} tr[N<<5];
void pushdown(int u) {
if(tr[u].tag!=0) {
tr[u<<1].tag+=tr[u].tag;
tr[u<<1|1].tag+=tr[u].tag;
tr[u<<1].val+=tr[u].tag;
tr[u<<1|1].val+=tr[u].tag;
tr[u].tag=0;
}
}
void pushup(int u) {
tr[u].val=max(tr[u<<1].val,tr[u<<1|1].val);
// cout<<"修改"<<u<<"号节点的值为"<<tr[u].val<<endl;
}
void build(int u,int l,int r) {
tr[u].tag=0;
tr[u].val=0;
if(l==r) {
return;
}
int m=l+(r-l)/2;
build(u<<1,l,m);
build(u<<1|1,m+1,r);
}
void update(int u,int l,int r,int st,int en,int k) {
if(st<=l&&r<=en) {
tr[u].val+=k;
tr[u].tag+=k;
// cout<<"修改"<<u<<"号节点的值为"<<tr[u].val<<endl;
return;
}
if(l!=r)pushdown(u);
int m=l+(r-l)/2;
if(st<=m)update(u<<1,l,m,st,en,k);
if(en>m)update(u<<1|1,m+1,r,st,en,k);
pushup(u);
}
struct _star {
int x,y,light;
bool operator<(const _star& t) const {
if(x==t.x)return light<t.light;
else return x<t.x;
}
} star[N];
// end code
//#define DEBUG
int main() {
//提高cin,cout的速度
ios::sync_with_stdio(false),cin.tie(0),cout.tie(0);
#ifdef DEBUG
freopen("P1502.in","r",stdin);
// freopen("P1502.ans","w",stdout);
#endif
// begin main code
cin>>T;
while(T--) {
cin>>n>>W>>H;
int x,y,light;
int maxy=0;
int cnt=1;
vector<int> v;
map<int,int> ymap;
FOR(i,1,n) {
cin>>x>>y>>light;
maxy=max(maxy,y);
star[2*i-1].x=x;
star[2*i-1].y=y;
star[2*i-1].light=light;
star[2*i].x=x+W;
star[2*i].y=y;
star[2*i].light=-light;
v.push_back(y);
v.push_back(y+H-1);
}
sort(v.begin(),v.end());
int cur=v[0];
FOR(i,1,v.size()-1) {
if(v[i]!=cur) {
cnt++;
cur=v[i];
}
ymap[v[i]]=cnt;
}
sort(star+1,star+n*2+1);
star[2*n+1].x=-1;
// db1(maxy+H);
build(1,1,cnt);
int ans=0;
FOR(i,1,2*n) {
// cout<<star[i].y<<"到"<<star[i].y+H-1<<"加上"<<star[i].light<<endl;
update(1,1,cnt,ymap[star[i].y],ymap[star[i].y+H-1],star[i].light);
if(star[i].x!=star[i+1].x) {
ans=max(ans,tr[1].val);
}
}
cout<<ans<<endl;
}
// end code
#ifdef DEBUG
fclose(stdin);
// fclose(stdout);
#endif
return 0;
}