cometoj 茶颜悦色|扫描线+懒惰标记

Posted l999q

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了cometoj 茶颜悦色|扫描线+懒惰标记相关的知识,希望对你有一定的参考价值。

传送门

题目描述

茶颜悦色也太好喝了!鸡尾酒在长沙的各种茶颜悦色的店铺中流连忘返。他发现长沙有炒鸡多的茶颜悦色店,走两步就能遇到一家。

“方圆一公里能有十家茶颜悦色!”鸡尾酒感叹了起来。

于是他想到了一个问题:最密集的地方,能有多少家茶颜悦色的店?

鸡尾酒将长沙地图用一个二维平面表示,他统计出了每个茶颜悦色店铺的坐标。

他想知道,在一个边长为 k 且底边平行于 x 轴的正方形中,最多有多少家茶颜悦色。

若茶颜悦色恰好在正方形的边上,也算在正方形之中。

 

输入描述

输入第一行包含两个正整数 n, (n10^5,k10^9) 代表茶颜悦色店的数量和正方形的边长。

接下来 n 行每行有两个整数,描述一家茶颜悦色店的坐标 xi,yi? (0xi?,yi?10^9) 保证不会出现重复的坐标。

 

输出描述

输出一行一个正整数表示答案。

 

样例输入 1 

4 2
1 1
3 1
3 4
2 2

样例输出 1

 3

 

题意:一个二维平面中有n个点,现在有个位置任意的k*k的矩形,问它里面最多能有多少点。

题解:我们可以把这个题转化为以(xi,yi)为左下角坐标,(xi+k,yi+k)为右上角坐标的矩形中,最多能有几个个矩形重合。然后我们就可以愉快的用扫描线来处理了:我们将竖直的直线从左到右依次扫过各个矩形,扫过矩形左边界时cnt++,扫过右边界时cnt--。维护最大cnt值即可。

   这题要注意的是:恰好在正方形的边上,也算在正方形之中。也就是说如果有一个矩形的右边界与另一个矩形的左边界重合的话,我们先加再减。对于这一点我们可以在存矩阵右边界时使其加一,也可以排序线段时处理。

   这题与POJ2482窗内的星星相似,不过一个算边界一个不算边界,一个先加后减一个先减后加。

代码:

技术图片
#include <bits/stdc++.h>
using namespace std;
#define ll long long
const int N = 2e5 + 10;
struct node
    ll x,y1,y2;
    int val;
    node()
    node(ll x,ll y1,ll y2,int val) 
        this->x = x; this->y1 = y1; this->y2 = y2; this->val = val;
    
    bool operator <(const node &t)const 
        //if (x==t.x) return val > t.val;    //排序时处理
        return x<t.x;
    
;
struct Tree
    int l,r,cnt,lazy;
T[N<<2];
vector<ll> v;
vector<node> a;
void build(int rt,int l,int r) 
    T[rt].l = l; T[rt].r = r;
    T[rt].cnt = 0; T[rt].lazy = 0;
    if (l==r) return;
    int mid = (l+r)>>1;
    build(rt<<1,l,mid);
    build(rt<<1|1,mid+1,r);

void down(int rt) 
    if (T[rt].lazy) 
        T[rt<<1].cnt += T[rt].lazy;
        T[rt<<1].lazy += T[rt].lazy;
        T[rt<<1|1].cnt += T[rt].lazy;
        T[rt<<1|1].lazy += T[rt].lazy;
        T[rt].lazy = 0;
    

void update(int rt,int l,int r,int val) 
    if (l <= T[rt].l && r >= T[rt].r) 
        T[rt].cnt += val;
        T[rt].lazy += val;
        return;
    
    down(rt);
    int mid = (T[rt].l+T[rt].r)>>1;
    if (l <= mid) update(rt<<1,l,r,val);
    if (r > mid) update(rt<<1|1,l,r,val);
    T[rt].cnt = max(T[rt<<1].cnt,T[rt<<1|1].cnt);

int main() 
    int n;
    ll k,x,y;
    scanf("%d%lld",&n,&k);
    for (int i = 0; i < n; i++) 
        scanf("%lld%lld",&x,&y);
        v.push_back(y);
        v.push_back(y+k);
        a.push_back(node(x,y,y+k,1));
        a.push_back(node(x+k+1,y,y+k,-1)); //存的时候右边界x坐标+1
    
    sort(a.begin(),a.end());
    sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end());
    n = v.size();
    build(1,0,n);
    n = a.size();
    int ans = 0;
    for (int i = 0; i < n; i++) 
        int l = lower_bound(v.begin(),v.end(),a[i].y1) - v.begin();
        int r = lower_bound(v.begin(),v.end(),a[i].y2) - v.begin();
        update(1,l,r,a[i].val);
        ans = max(ans,T[1].cnt);
    
    printf("%d\\n",ans);
    return 0;
View Code

 



以上是关于cometoj 茶颜悦色|扫描线+懒惰标记的主要内容,如果未能解决你的问题,请参考以下文章

暑假集训-8.15总结

茶颜悦色老板在8000人大群怒怼员工,唱反调的一律开除,一看月薪只发了1000多......

吸取“顶流”茶颜悦色“教训”,虎头局应该尽快走出长沙吗?

蜜雪冰城茶颜悦色“卷”向咖啡赛道

一场员工高管间的口水战,员工输了

“顶流”长沙,如何发展MCN?