LOJ#106. 二逼平衡树 树套树
这里写的是线段树套权值线段树和 set.
写代码的时间大概是 40 min,然后调试时间是 10 分钟左右,感觉这种数据结构题写的时候仔细检查的话还是比较好调的.
code:
#include <bits/stdc++.h>
#define ll long long
#define N 50009
#define lson s[x].ls
#define rson s[x].rs
#define inf 100000000
#define INF 2147483647
#define setIO(s) freopen(s".in","r",stdin)
using namespace std;
set<int>se[N<<2];
set<int>::iterator it;
int n,m,tot,rt[N<<2],a[N];
struct data { int ls,rs,sum; }s[N*400];
int Getpr(int x,int v)
{
it=se[x].lower_bound(v);
if(it==se[x].begin()) return -INF;
it--;return *it;
}
int Getaf(int x,int v)
{
it=se[x].lower_bound(v);
if(it==se[x].end()) return INF;
if((*it)>v) return *it;
it++;
if(it==se[x].end()) return INF;
return *it;
}
int update(int &x,int l,int r,int p,int v)
{
if(!x) x=++tot;
s[x].sum+=v;
if(l==r) return s[x].sum;
int mid=(l+r)>>1;
if(p<=mid) return update(lson,l,mid,p,v);
else return update(rson,mid+1,r,p,v);
}
int query(int x,int l,int r,int v)
{
if(!x) return 0;
int mid=(l+r)>>1;
if(v>mid) return s[lson].sum+query(rson,mid+1,r,v);
else return query(lson,l,mid,v);
}
void Modify(int l,int r,int now,int p,int v,int op)
{
int flag=update(rt[now],-inf,inf,v,op);
if(op==1) se[now].insert(v);
if(op==-1&&!flag) se[now].erase(v);
if(l==r) return;
int mid=(l+r)>>1;
if(p<=mid) Modify(l,mid,now<<1,p,v,op);
else Modify(mid+1,r,now<<1|1,p,v,op);
}
int Ask_rank(int l,int r,int now,int L,int R,int k)
{
if(l>=L&&r<=R) return query(rt[now],-inf,inf,k);
int mid=(l+r)>>1,re=0;
if(L<=mid) re+=Ask_rank(l,mid,now<<1,L,R,k);
if(R>mid) re+=Ask_rank(mid+1,r,now<<1|1,L,R,k);
return re;
}
int Ask_pr(int l,int r,int now,int L,int R,int k)
{
if(l>=L&&r<=R) return Getpr(now,k);
int mid=(l+r)>>1,re=-INF;
if(L<=mid) re=max(re,Ask_pr(l,mid,now<<1,L,R,k));
if(R>mid) re=max(re,Ask_pr(mid+1,r,now<<1|1,L,R,k));
return re;
}
int Ask_af(int l,int r,int now,int L,int R,int k)
{
if(l>=L&&r<=R) return Getaf(now,k);
int mid=(l+r)>>1,re=INF;
if(L<=mid) re=min(re,Ask_af(l,mid,now<<1,L,R,k));
if(R>mid) re=min(re,Ask_af(mid+1,r,now<<1|1,L,R,k));
return re;
}
int Ask_IS(int l,int r,int now,int L,int R,int k)
{
if(l>=L&&r<=R) return *se[now].lower_bound(k)==k;
int mid=(l+r)>>1,re=0;
if(L<=mid) re|=Ask_IS(l,mid,now<<1,L,R,k);
if(R>mid) re|=Ask_IS(mid+1,r,now<<1|1,L,R,k);
return re;
}
char *p1,*p2,buf[100000];
#define nc() (p1==p2&&(p2=(p1=buf)+fread(buf,1,100000,stdin),p1==p2)?EOF:*p1++)
int rd()
{
int x=0,flag=1; char c;
while(c<48) { c=nc(); if(c=='-') flag=-1; }
while(c>47) { x=(((x<<2)+x)<<1)+(c^48),c=nc(); }
return x*flag;
}
int main()
{
// setIO("input");
int x,y,z,l,r,k,L,R,mid,ans;
n=rd(),m=rd();
for(int i=1;i<=n;++i) x=rd(),Modify(1,n,1,i,x,1),a[i]=x;
for(int i=1;i<=m;++i)
{
z=rd();
if(z==1)
{
l=rd(),r=rd(),k=rd();
printf("%d\n",Ask_rank(1,n,1,l,r,k)+1);
}
if(z==2)
{
l=rd(),r=rd(),k=rd(),--k;
ans=L=-inf,R=inf;
while(L<=R)
{
mid=(L+R)>>1;
if(Ask_rank(1,n,1,l,r,mid)>=k)
ans=mid,R=mid-1;
else L=mid+1;
}
if(Ask_IS(1,n,1,l,r,ans)) {
printf("%d\n",ans);
continue;
}
int X=Ask_pr(1,n,1,l,r,ans);
int Y=Ask_af(1,n,1,l,r,ans);
if(Y!=INF)
{
if(Ask_rank(1,n,1,l,r,Y)==k) { printf("%d\n",Y); continue; }
}
printf("%d\n",X);
}
if(z==3)
{
x=rd(),y=rd();
Modify(1,n,1,x,a[x],-1);
Modify(1,n,1,x,y,1);
a[x]=y;
}
if(z==4)
{
l=rd(),r=rd(),k=rd();
printf("%d\n",Ask_pr(1,n,1,l,r,k));
}
if(z==5)
{
l=rd(),r=rd(),k=rd();
printf("%d\n",Ask_af(1,n,1,l,r,k));
}
}
return 0;
}

浙公网安备 33010602011771号