1. 程式人生 > >BZOJ1028 [HNOI2004]寵物收養所

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; }