【洛谷P1502】窗口的星星
好像跟POJ重题
这是一道扫描线的题。
由于窗口的大小已知,我们不妨换一下思路,把问题转化成这样:平面内有若干个矩形(大小就是窗口的大小,矩形左下角的位置就是某一颗星星的位置),每一个矩形覆盖的区域都有一个权值(星星的亮度),求某一位置,使得这个位置被覆盖的权值最大,最大值即答案。
为什么这样就是正确的?每一个窗口的大小都是固定的,假设我们把这个窗口的右上角放在刚刚所说的星星的矩形中,那么这颗星星一定能被看见。以此类推,假设我们把窗口的右上角放在尽可能多矩形的范围内(这里说的不太恰当,应该是放在权值加起来尽可能大的范围内),我们的答案就尽可能优,因此,我们只需要用扫描线求出最大的权值即可。
1 #include <iostream> 2 #include <cstdio> 3 #include <cstring> 4 #include <algorithm> 5 using namespace std; 6 const int N=10010; 7 int T; 8 struct line { 9 int x,y1,y2,v; 10 bool operator <(const line &xx) const { 11 if(x==xx.x) return v>xx.v; 12 return x<xx.x; 13 } 14 }a[N<<1]; 15 int n,val[N<<1][2],raw[N<<1]; 16 struct node { 17 int l,r; 18 int data,tag; 19 }s[N<<3]; 20 int ans,t,w,h; 21 inline void build(int now,int l,int r) { 22 s[now].l=l; 23 s[now].r=r; 24 s[now].data=s[now].tag=0; 25 if(l==r) return ; 26 int mid=l+r>>1; 27 build(now<<1,l,mid); 28 build(now<<1|1,mid+1,r); 29 } 30 inline void pushdown(int now) { 31 if(s[now].tag) { 32 int v=s[now].tag; 33 s[now<<1].tag+=v; 34 s[now<<1|1].tag+=v; 35 s[now<<1].data+=v; 36 s[now<<1|1].data+=v; 37 s[now].tag=0; 38 } 39 } 40 void updata(int now,int l,int r,int v) { 41 if(l<=s[now].l&&s[now].r<=r) { 42 s[now].data+=v; 43 s[now].tag+=v; 44 return ; 45 } 46 pushdown(now); 47 int mid=s[now].l+s[now].r>>1; 48 if(l<=mid) updata(now<<1,l,r,v); 49 if(r>mid) updata(now<<1|1,l,r,v); 50 s[now].data=max(s[now<<1].data,s[now<<1|1].data); 51 } 52 int main() { 53 scanf("%d",&T); 54 while(T--) { 55 ans=t=0; 56 scanf("%d%d%d",&n,&w,&h); 57 for(int i=1;i<=n;i++) { 58 int x,y,z; 59 scanf("%d%d%d",&x,&y,&z); 60 a[2*i-1]=(line){x,y,y+h,z}; 61 a[2*i]=(line){x+w-1,y,y+h,-z}; 62 raw[++t]=y; 63 raw[++t]=y+h-1; 64 } 65 sort(a+1,a+2*n+1); 66 sort(raw+1,raw+t+1); 67 t=unique(raw+1,raw+t+1)-raw-1; 68 for(int i=1;i<=2*n;i++) { 69 val[i][0]=lower_bound(raw+1,raw+t+1,a[i].y1)-raw; 70 val[i][1]=lower_bound(raw+1,raw+t+1,a[i].y2)-raw; 71 } 72 build(1,1,t); 73 for(int i=1;i<=2*n;i++) { 74 updata(1,val[i][0],val[i][1]-1,a[i].v); 75 ans=max(ans,s[1].data); 76 } 77 printf("%d\n",ans); 78 } 79 return 0; 80 }