感觉来到这里都是大佬,现在开始学线段树。压力大。
这道题给我看了几千字情书,才是题目!!!
#include<iostream> #include<cstdio> #include<algorithm> #include<cstring> using namespace std; struct data { long long x,y1,k,y2; };data f[50010]; struct data2 { long long l,r,lazy,max1; }f1[200000]; long long map[50010]; void pushup(int p) { f1[p].max1=max(f1[p<<1].max1,f1[p<<1|1].max1)+f1[p].lazy; } void build(long long l,long long r,long long p) { f1[p].max1=f1[p].lazy=0; f1[p].l=map[l]; f1[p].r=map[r]; if(r-l==1) return ; int mid=(l+r)>>1; build(l,mid,p<<1); build(mid,r,p<<1|1); pushup(p); } bool cmp(data a,data b) { if(a.x!=b.x) return a.x<b.x; else return a.k<0;//先扫描k为负数的 } void update(long long l1,long long r1,long long k,long long p) { if(f1[p].l>=l1&&f1[p].r<=r1)//当操作区域在当前区域内时 { f1[p].max1+=k; f1[p].lazy+=k; return ; } if(l1<f1[p<<1].r) update(l1,min(f1[p<<1].r,r1),k,p<<1); if(r1>f1[p<<1|1].l) update(max(f1[p<<1|1].l,l1),r1,k,p<<1|1); pushup(p); } int main() { long long n,w,h,x,y,k; while(scanf("%I64d %I64d %I64d", &n, &w, &h) != EOF) { int step=0,sum=1; for(int i=1;i<=n;i++) { scanf("%I64d%I64d%I64d",&x,&y,&k); f[step].x=x;//结构体建矩形 f[step].y1=y; f[step].y2=y+h; f[step++].k=k; f[step].x=x+w; f[step].y1=y; f[step].y2=y+h; f[step++].k=-k; map[sum++]=y;//离散化 map[sum++]=y+h; } sort(map+1,map+sum);//排序 sum=unique(map+1,map+sum)-(map+1);//去重 求元素个数 sort(f,f+step,cmp);//离散化数组排序 build(1,sum,1); // cout<<"sum:"<<sum<<endl; long long maxx=0; for(int i=0;i<step;i++) { update(f[i].y1,f[i].y2,f[i].k,1); if(f[i].k>0) maxx=max(maxx,f1[1].max1); } /*for(int i=1;i<=n;i++) cout<<f1[i].l<<" "<<f1[i].r<<" "<<f1[i].lazy<<endl; for(int i=1;i<=sum;i++) cout<<map[i]<<endl;*/ printf("%I64d\n",maxx); } }