zoukankan      html  css  js  c++  java
  • 窗口的星星

    洛咕

    题意:天真的小卡总是希望能够在晚上能看到最多最亮的星星,但是窗子的大小是固定的,边也必须和地面平行。这时小卡使用了超能力(透视术)知道了墙后面每个星星的位置和亮度,但是小卡发动超能力后就很疲劳,只好拜托你告诉他最多能够有总和多亮的星星能出现在窗口上。

    分析:巧妙地转化为扫描线.对于每颗星星,转化为一个以该星星为左下角,宽为W,高为H的矩形.意思就是以这个矩形内的任意一点为右上角作矩形,就能包括到这颗星星.所以题目转化为了有n个矩形,每个矩形的收益就是这颗星星的价值.(n<=10000,1<=W,H<=1000000.)

    转化之后就是扫描线板子题了.线段树维护区间最大值就行了.因为有区间赋值操作,虽然不需要维护区间和,但是要用到延迟标记.

    #include<iostream>
    #include<cstdio>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #include<queue>
    #include<map>
    #include<set>
    #define ll long long
    using namespace std;
    inline int read(){
        int x=0,o=1;char ch=getchar();
        while(ch!='-'&&(ch<'0'||ch>'9'))ch=getchar();
        if(ch=='-')o=-1,ch=getchar();
        while(ch>='0'&&ch<='9')x=x*10+ch-'0',ch=getchar();
        return x*o;
    }
    const int N=5e5+5;//开大一点
    int a[N];
    struct line{int x,y1,y2,k;}e[N];
    inline bool cmp(const line &x,const line &y){
    	return x.x==y.x?x.k<y.k:x.x<y.x;
    }
    struct xd_tree{int l,r;ll add,maxn;}t[N<<1];
    inline void build(int p,int l,int r){
    	t[p].l=l;t[p].r=r;
    	if(l==r)return;
    	int mid=(l+r)>>1;
    	build(p<<1,l,mid);build(p<<1|1,mid+1,r);
    }
    inline void spread(int p){
        if(!t[p].add)return;
    	t[p<<1].maxn+=t[p].add;
    	t[p<<1|1].maxn+=t[p].add;
        t[p<<1].add+=t[p].add;
    	t[p<<1|1].add+=t[p].add;
    	t[p].add=0;
    }
    inline void change(int p,int l,int r,int v){
    	if(l<=t[p].l&&t[p].r<=r){t[p].add+=v;t[p].maxn+=v;return;}
    	spread(p);int mid=(t[p].l+t[p].r)>>1;
    	if(l<=mid)change(p<<1,l,r,v);
    	if(r>mid)change(p<<1|1,l,r,v);
    	t[p].maxn=max(t[p<<1].maxn,t[p<<1|1].maxn);
    }
    int main(){
    	int T=read();
    	while(T--){
    		int n=read(),w=read(),h=read(),tot=0;
    		for(int i=1;i<=n;++i){
    			int x=read(),y=read(),c=read();
    			e[(i<<1)-1].x=x;e[(i<<1)-1].y1=y;e[(i<<1)-1].y2=y+h-1;e[(i<<1)-1].k=c;
    			e[i<<1].x=x+w;e[i<<1].y1=y;e[i<<1].y2=y+h-1;e[i<<1].k=-c;
    			a[++tot]=y;a[++tot]=y+h-1;
    		}
    		sort(a+1,a+tot+1);
    		int sum=unique(a+1,a+tot+1)-a-1;
    		n<<=1;
    		for(int i=1;i<=n;++i){
    			int pos1=lower_bound(a+1,a+sum+1,e[i].y1)-a;
    			int pos2=lower_bound(a+1,a+sum+1,e[i].y2)-a;
    			e[i].y1=pos1;e[i].y2=pos2;
    		}
    		sort(e+1,e+n+1,cmp);
    		ll ans=0;build(1,1,n);
    		for(int i=1;i<=n;++i){
    			change(1,e[i].y1,e[i].y2,e[i].k);
    			ans=max(ans,t[1].maxn);
    		}
    		printf("%lld
    ",ans);
    	}
        return 0;
    }
    
    
  • 相关阅读:
    C#中如何求时间间隔?
    Ilist<T> 转换成 DataSet
    EditPlus 快捷键
    Array和ArrayList的异同点
    sql server 查询数据库中有多少个表
    jquery + Css 模式对话框
    paddingtop、margintop和top的区别
    JQuery之ContextMenu(右键菜单)
    关于TextBox的Enable与ReadOnly属性
    AjaxToollit 3.5 使用整理
  • 原文地址:https://www.cnblogs.com/PPXppx/p/11522344.html
Copyright © 2011-2022 走看看