• luogu P1502 窗口的星星


    题目链接

    P1502 窗口的星星

    题解

    扫描线+线段树
    线段树的每一个节点处理的是左边框放在当前x-1位置时的框内星星的亮度大小
    按照x坐标进行离散化,得到离散化后每一个坐标x的可影响的范围
    维护扫描线,扫到可以加某颗星星就把星星加进去,扫到该出来的时候就把星星搞出来,线段树维护一下

    代码

    #include<cstdio> 
    #include<cstring>
    #include<algorithm>
     
    const int maxn = 100007; 
    
    int n,w,h;
    int pou[maxn << 2],T[maxn << 2],tag[maxn << 2]; 
    
    struct P {
        int x,y,l,k,ymax,id;  
    }star[maxn << 2];  
    inline bool cmp1(P a,P b) { return a.y < b.y; } 
    inline bool cmp2(P a,P b) { if(a.id == b.id) return a.k < b.k; return a.id < b.id; } 
    inline bool cmp3(P a,P b) { if(a.x == b.x) return a.k < b.k; return a.x < b.x;  } 
    void pushdown(int x,int l,int r) { 
        if(!tag[x]) return;  
        if(l == r) { tag[x] = 0; return; } 
        int mid = l + r >> 1; 
        tag[x << 1] += tag[x]; tag[x << 1 | 1] += tag[x]; 
        T[x << 1] += tag[x];  T[x << 1 | 1]+=tag[x]; 
        tag[x] = 0; 
    } 
    
    void modify(int x,int l,int r,int tl,int tr,int val){
        pushdown(x,l,r);  
        if(tl <= l && r <= tr) { 
            tag[x] = val; T[x] += val; 
            return; 
        } 
        int mid = (l + r) >> 1; 
        if(tl <= mid) modify(x << 1,l,mid,tl,tr,val); 
        if(mid < tr) modify(x << 1 | 1,mid + 1,r,tl,tr,val); 
        T[x] = std::max(T[x << 1],T[x << 1 | 1]); 
    } 
    void init() { 
        memset(T,0,sizeof(T)); 
        memset(tag,0,sizeof(tag));  
        scanf("%d%d%d",&n,&w,&h);  
        for(int x,y,l,i = 1;i <= n ;++ i) {   
            scanf("%d%d%d",&x,&y,&l);  
            star[i] = (P) {x, y, l, 1};  
            star[i + n] = (P){ x + w - 1, y, -l, 2};  
            star[i + (n << 1)].y = y + h - 1;  
            star[i + (n << 1)].k = 3;   
            star[i].id = star[i + n].id = star[i + (n << 1)].id = i;  
        } 
    }  
     
    void solve() {  
        std::sort(star + 1,star + n * 3 + 1,cmp1);  
        int cnt = 0;  
        for(int i = 1;i <= n * 3;++ i) pou[i] = star[i].y;  
        for(int i = 1;i <= n * 3;++ i)  
            if(star[i].y == pou[i - 1]) star[i].y = star[i - 1].y;  
            	else star[i].y =++ cnt;  
        std::sort(star + 1,star + n * 3 + 1,cmp2);  
        for(int i = 1;i <= n * 3;i += 3) star[i].ymax = star[i + 1].ymax = star[i + 2].y;  
        for(int i = 3;i <= n << 1;++ i)  star[i] = star[i + ((i - 1) >> 1)];  
        std::sort(star + 1,star + (n << 1) + 1,cmp3);   
        int ans = 0; 
        for(int i = 1;i <= n << 1;++ i) { 
            modify(1,0,cnt,star[i].y,star[i].ymax,star[i].l); 
            ans = std::max(ans,T[1]);
        } 
        printf("%d
    ",ans); 
        return ; 
    } 
    int main() {  
        int t; scanf("%d",&t); 
        while(t --) {  
        	init();  
            solve(); 
        }  
        return 0; 
    } 
    
  • 相关阅读:
    软件需求与分析课堂讨论一
    问题账户需求分析
    个人阅读计划
    个人总结
    团队其他各组项目意见
    大白鱼备考云笔记冲刺周期第七天
    大白鱼备考云笔记冲刺周期第六天
    大白鱼备考云笔记冲刺周期第五天
    大白鱼备考云笔记冲刺周期第四天
    大白鱼备考云笔记冲刺周期第三天
  • 原文地址:https://www.cnblogs.com/sssy/p/9461928.html
Copyright © 2020-2023  润新知