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

  

posted @ 2020-06-10 20:56  EM-LGH  阅读(138)  评论(0编辑  收藏  举报