More than 2019 cattle off summer school camp (tenth field) F.Popping Balloons (segment tree)

Meaning of the questions: You are given n points sideways now let you draw three lines spacing r then draw three lines vertically is the same distance r now let you find the most points after

Ideas: We first built a tree on the line y intervals and then enumerate the x-axis overlap each update point and then go back and find a maximum update

#include <bits/stdc++.h>
using namespace std;
const double pi = acos(-1.0);
const int N = 1e5+7;
const int inf = 0x3f3f3f3f;
const double eps = 1e-6;
typedef long long ll;
const ll mod = 1e7+9;
int n,d;
struct tree{
    int l,r;
    ll v;
}t[N<<4];
int yy[N<<2];
vector<int> xx[N<<2];
void pushup(int p){
    t[p].v=max(t[p<<1].v,t[p<<1|1].v);
}
void build(int p,int l,int r){
    t[p].l=l; t[p].r=r;
    if(l==r){
        t[p].v=yy[l]+yy[l+d]+yy[l+2*d];
        return ;
    }
    int mid=(l+r)>>1;
    build(p<<1,l,mid);
    build(p<<1|1,mid+1,r);
    pushup(p);
}
void update(int p,int x,int val){
    if(t[p].l==t[p].r&&t[p].l==x){
        t[p].v+=val;
        return ;
    }
    int mid=(t[p].l+t[p].r)>>1;
    if(x<=mid) update(p<<1,x,val);
    else update(p<<1|1,x,val);
    pushup(p);
}
void work(int x,int val){
    update(1,x,val);
    if(x-d>=0) update(1,x-d,val);
    if(x-2*d>=0) update(1,x-2*d,val);
}
int main(){
    ios::sync_with_stdio(false);
    cin.tie(0); cout.tie(0);
    cin>>n>>d;
    int pox=0; int poy=0;
    for(int i=1;i<=n;i++){
        int x,y; cin>>x>>y;
        pox=max(pox,x); poy=max(poy,y);
        yy[y]++;
        xx[x].push_back(y);
    }
    build(1,0,poy);
    ll ans=0;
    for(int i=0;i<=pox;i++){
        ll tmp=xx[i].size()+xx[i+d].size()+xx[i+2*d].size();
        for(int j=0;j<xx[i].size();j++){
            work(xx[i][j],-1);
        }
        for(int j=0;j<xx[i+d].size();j++){
            work(xx[i+d][j],-1);
        }
        for(int j=0;j<xx[i+2*d].size();j++){
            work(xx[i+2*d][j],-1);
        }
        ans=max(ans,t[1].v+tmp);
        for(int j=0;j<xx[i].size();j++){
            work(xx[i][j],1);
        }
        for(int j=0;j<xx[i+d].size();j++){
            work(xx[i+d][j],1);
        }
        for(int j=0;j<xx[i+2*d].size();j++){
            work(xx[i+2*d][j],1);
        }
    }
    cout<<ans<<endl;
}

 

Guess you like

Origin www.cnblogs.com/wmj6/p/11372102.html