CCPC-Wannafly & Comet OJ 夏季欢乐赛(2019)茶颜悦色

    离散化 + 扫描线 + 用线段树维护, 核心是扫描线的思想 

#include <bits/stdc++.h>
using namespace std;
const int N = 200005;

struct Line
{
    int x1, x2, h, flag;
    bool operator < (const Line &p) const{
        return h < p.h;
    }
}P[N];
vector<int>vec;
int n, k;

struct Segment
{
    int l, r, ans, lazy;
}t[N<<2];

void Build(int p, int l, int r)
{
    t[p].l = l;t[p].r = r;
    if(l==r){
        t[p].ans=t[p].lazy=0;
        return ;
    }
    int mid = (l + r) >> 1;
    Build(p<<1,l,mid);
    Build(p<<1|1,mid+1,r);
    t[p].ans = max(t[p<<1].ans,t[p<<1|1].ans);
    t[p].lazy = 0;
}

void push_down(int p)
{
    if(t[p].lazy){
        t[p<<1].ans += t[p].lazy;
        t[p<<1|1].ans += t[p].lazy;
        t[p<<1].lazy += t[p].lazy;
        t[p<<1|1].lazy += t[p].lazy;
        t[p].lazy = 0;
    }
}

void Update(int p, int L, int R, int C)
{
    int l = t[p].l, r = t[p].r;
    if(L <= l && r <= R){
        t[p].ans += C;
        t[p].lazy += C;
        return ;
    }
    push_down(p);
    int mid = (l + r) >> 1;
    if(L<=mid)Update(p<<1, L, R, C);
    if(mid<R)Update(p<<1|1, L, R, C);
    t[p].ans=max(t[p<<1].ans, t[p<<1|1].ans);
}

int query(int p, int L, int R)
{
    int l = t[p].l, r = t[p].r;
    if(L <= l && r <= R){
        return t[p].ans;
    }
    push_down(p);
    int mid = (l + r) >> 1,ans = 0;
    if(L <= mid)ans = max(ans, query(p<<1,L,R));
    if(mid < R)ans = max(ans, query(p<<1|1,L,R));
    return ans;
}

int main()
{
    scanf("%d%d",&n,&k);int cnt = 0;
    for(int i = 1;i <= n; i++){
        int a,b;scanf("%d%d",&a,&b);
        P[++cnt] = (Line){a - k, a, b - k, 1};
        P[++cnt] = (Line){a - k, a, b + 1, -1};
        vec.push_back(a - k);
        vec.push_back(a);
    }
    sort(vec.begin(),vec.end());
    int m=unique(vec.begin(),vec.end()) - vec.begin();
    n <<= 1;Build(1, 1, n);
    sort(P+1,P+n+1);int ans = 0;
    for(int i = 1;i <= n; i++){
        int L = lower_bound(vec.begin(),vec.end(),P[i].x1) - vec.begin();
        int R = lower_bound(vec.begin(),vec.end(),P[i].x2) - vec.begin();
        Update(1, L, R, P[i].flag);
        ans = max(ans, t[1].ans);
    }
    printf("%d\n",ans);
    return 0;
}
/*
4 2
1 1
3 1
3 4
2 2
*/

 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值