BZOJ2951 [Poi2001]Goldmine

来源:互联网 发布:教学过程最优化 编辑:程序博客网 时间:2024/06/09 13:39

把所有点按x坐标排序,然后双指针扫一下,一个指针扫右边界,另一个扫当前右边界的时候的最靠左的左边界,线段树维护每个下边界的答案

#include<iostream>#include<cstdio>#include<cstdlib>#include<cstring>#include<ctime>#include<cmath>#include<algorithm>#include<iomanip>#include<vector>#include<map>#include<set>#include<bitset>#include<queue>#include<stack>using namespace std;#define MAXN 15010#define MAXM 60010#define INF 1000000000#define MOD 1000000007#define eps 1e-8#define ll long longstruct pt{    int x;    int y;    friend bool operator <(pt x,pt y){        return x.x<y.x;    }};int n,s,w;pt a[MAXN];int v[MAXM<<2],ch[MAXM<<2];int ans;inline void ud(int x){    v[x]=max(v[x<<1],v[x<<1|1]);}inline void toch(int x,int y){    v[x]+=y;    ch[x]+=y;}inline void pd(int x){    if(ch[x]){        toch(x<<1,ch[x]);        toch(x<<1|1,ch[x]);        ch[x]=0;    }}void change(int x,int y,int z,int l,int r,int cv){    if(y==l&&z==r){        toch(x,cv);        return ;    }    int mid=y+z>>1;    pd(x);    if(r<=mid){        change(x<<1,y,mid,l,r,cv);    }else if(l>mid){        change(x<<1|1,mid+1,z,l,r,cv);    }else{        change(x<<1,y,mid,l,mid,cv);        change(x<<1|1,mid+1,z,mid+1,r,cv);    }    ud(x);}int main(){    int i;    int lim=30000;    scanf("%d%d%d",&s,&w,&n);    for(i=1;i<=n;i++){        scanf("%d%d",&a[i].x,&a[i].y);    }    sort(a+1,a+n+1);    int wzh=1;    for(i=1;a[i].x<=a[1].x+s;i++){        change(1,-lim,lim,a[i].y,min(lim,a[i].y+w),1);    }    ans=v[1];    for(;i<=n;i++){        int tx=a[i].x;        while(a[i].x==tx&&i<=n){            change(1,-lim,lim,a[i].y,min(lim,a[i].y+w),1);            i++;        }        i--;        while(a[wzh].x<a[i].x-s){            change(1,-lim,lim,a[wzh].y,min(lim,a[wzh].y+w),-1);            wzh++;        }        ans=max(ans,v[1]);    }    printf("%d\n",ans);    return 0;} /*1 2120 01 12 23 34 55 54 21 40 55 02 33 2 */


0 0
原创粉丝点击