听说flaze太久没有更blog了……然而学渣被文化课虐的欲生欲死【假装自己五一没有花一天去ACG展子排队】
学会了离散化的新姿势
顺便感谢cyz大爷帮忙debug【虽然最后发现是flaze写丑了重新码一遍就A了【至于I64d啥的都是浮云【望天默念三声long long mian()
二话不说,上代码。。。
都是套路,第一次写没有inqry的线段树感觉连字都不会打了【
//一直没有写过扫描线……只会口胡……现在终于去水了一道题,感觉自己萌萌哒
#include<cstdio>
#include<algorithm>
#include<cstring>
#include<iostream>
using namespace std; int n,W,H;
const int MAXN=10057;
struct t1{
long long x,y1,y2,l; //y1是下界,y2是上界,x是横坐标;
bool operator < (const t1 xx) const {
// if(x==xx.x) return l<xx.l;
return x<xx.x;
}
}rec[MAXN<<2];
int y[MAXN<<2],cnt_y;
struct t2{
long long dt,lzy;
}node[MAXN<<4];
void pushdown(int now){
node[now<<1].dt+=node[now].lzy,node[now<<1|1].dt+=node[now].lzy;
node[now<<1].lzy+=node[now].lzy,node[now<<1|1].lzy+=node[now].lzy;
node[now].lzy=0;
}
//离散化新姿势,线段树用起来有奇效 只要把原来的l,r,mid改成排序后的数组y的下标就好了 嗯感性理解会觉得简直够了
void Modify(int now,int l,int r,long long L,long long R,long long v){
// cout<<y[l]<<' '<<y[r]<<' '<<L<<' '<<R<<endl;
if(L<=y[l]&&y[r]<=R){
node[now].dt+=v;
node[now].lzy+=v;
return ;
}
pushdown(now);
int mid=(l+r)>>1;
if(L<=y[mid]) Modify(now<<1,l,mid,L,R,v);
if(y[mid+1]<=R) Modify(now<<1|1,mid+1,r,L,R,v);
node[now].dt=max(node[now<<1].dt,node[now<<1|1].dt);
}
long long ans;
int main(){
// freopen("1.txt","r",stdin);
while(~scanf("%d%d%d",&n,&W,&H)){
ans=0;
memset(rec,0,sizeof(rec));
cnt_y=0;
for(int i=1;i<=n;++i){
//把星星变成一个面,窗户当成一个点【用心感受x
//展开的时候,每个rec只记录一条平行于纵坐标的线(矩形就拆成那种左边一个标记右边一个的
scanf("%I64d%I64d%I64d",&rec[i].x,&rec[i].y1,&rec[i].l);
y[2*i-1]=rec[i].y2=rec[i].y1+H-1;
y[2*i]=rec[i].y1;
rec[i+n]=rec[i];
rec[i+n].x=rec[i].x+W;
rec[i+n].l=-rec[i].l;
}
sort(rec+1,rec+2*n+1);
sort(y+1,y+2*n+1);
cnt_y=unique(y+1,y+2*n+1)-y-1;
for(int i=1;i<=2*n;++i){
Modify(1,1,cnt_y,rec[i].y1,rec[i].y2,rec[i].l);
//对于每个位置,应该是把所有操作做完了才更新答案【所以下面那句】,至于为什么……本来这里应该删掉一些再加上的话,岂不是血崩了【感性理解】
if(i == 2 * n || rec[i+1].x!=rec[i].x)
ans=max(ans,node[1].dt);
}
printf("%I64d\n",ans);
}
return 0;
}