BZOJ1028 [HNOI2004]宠物收养所

感觉自己像个智障,一道谁题都wa了3,4次。。。

我是用权值线段树(感觉代码没少多少。可能是我不会精简,很多重复的操作。)

注意以后写题不要再犯sb错误了 k<<1|1写成k>>1|1 。。。还有注意取膜

#include<bits/stdc++.h>
using namespace std;
const int maxn=320010;
struct date{int opt,x;}da[maxn];
struct tp{int l,r,s;}tree[2][maxn];
vector<int>v;
int get_id(int x){return lower_bound(v.begin(),v.end(),x)-v.begin()+1;}
bool re;
int p[maxn];
void build(int k,int l,int r){
    tree[0][k].l=tree[1][k].l=l;
    tree[0][k].r=tree[1][k].r=r;
    if(l==r){p[l]=k;return ;}
    int mid=(l+r)>>1;
    build(k<<1,l,mid);
    build(k<<1|1,mid+1,r);
}
void update(int k,int pos){
    int l=tree[re][k].l,r=tree[re][k].r;
    tree[re][k].s++;
    if(l==r)return ;
    int mid=(l+r)>>1;
    if(pos<=mid)update(k<<1,pos);
    else update(k<<1|1,pos);
}
void del(int k,int pos){
    int l=tree[!re][k].l,r=tree[!re][k].r;
    tree[!re][k].s--;
    if(l==r)return ;
    int mid=(l+r)>>1;
    if(pos<=mid)del(k<<1,pos);
    else del(k<<1|1,pos);
}
int fi(int k,bool b){
    if(tree[!re][k].l==tree[!re][k].r)return tree[!re][k].l;
    if(b==0){
        if(tree[!re][k<<1|1].s)return fi(k<<1|1,b);
        else return fi(k<<1,b);
    }
    else{
        if(tree[!re][k<<1].s)return fi(k<<1,b);
        else return fi(k<<1|1,b);
    }
}
int main(){
    int n;
    cin>>n;
    for(int i=1;i<=n;++i){
        cin>>da[i].opt>>da[i].x;
        v.push_back(da[i].x);
    }
    sort(v.begin(),v.end());
    v.erase(unique(v.begin(),v.end()),v.end()); 
    build(1,1,n);
    int sz1=0,sz2=0,ans=0;
    for(int i=1;i<=n;++i){
        re=da[i].opt;
        if(da[i].opt==0){
            if(sz2==0)update(1,get_id(da[i].x)),sz1++;
            else{
                sz2--;
                int k=p[get_id(da[i].x)];
                int t1=-1,t2=-1,temp=0;
                if(tree[!re][k].s)t1=t2=get_id(da[i].x);
                else
                while(k!=0){
                    if(!tree[!re][k].s){k>>=1;continue;}
                    if(t1==-1&&temp!=k*2&&tree[!re][k<<1].s)t1=fi(k<<1,0);
                    if(t2==-1&&temp!=k*2+1&&tree[!re][k<<1|1].s)t2=fi(k<<1|1,1);
                    temp=k;
                    k>>=1;
                }
                if(t2==-1||t1!=-1&&da[i].x-v[t1-1]<=v[t2-1]-da[i].x)ans+=da[i].x-v[t1-1],del(1,t1);
                else ans+=v[t2-1]-da[i].x,del(1,t2);
            }
        }
        else{
            if(sz1==0)update(1,get_id(da[i].x)),sz2++;
            else{
                sz1--;
                int k=p[get_id(da[i].x)];
                int t1=-1,t2=-1,temp=0;
                if(tree[!re][k].s)t1=t2=get_id(da[i].x);
                else
                while(k!=0){
                    if(!tree[!re][k].s){k>>=1;continue;}
                    if(t1==-1&&temp!=k*2&&tree[!re][k<<1].s)t1=fi(k<<1,0);
                    if(t2==-1&&temp!=k*2+1&&tree[!re][k<<1|1].s)t2=fi(k<<1|1,1);
                    temp=k;
                    k>>=1;
                }
                if(t2==-1||t1!=-1&&da[i].x-v[t1-1]<=v[t2-1]-da[i].x)ans+=da[i].x-v[t1-1],del(1,t1);
                else ans+=v[t2-1]-da[i].x,del(1,t2);
            }
        }
        ans%=1000000;
    }
    cout<<ans;
    return 0;
}

 

posted @ 2018-12-09 19:31  lqsno1  阅读(79)  评论(0编辑  收藏  举报