pku2761 Feed the dogs

没什么好说的,和2104差不多,写个SBT模板直接套

 

#include <iostream>
#include 
<algorithm>
using namespace std;

#define MAXN 100001

int a[MAXN],n,m;
int key[3*MAXN],lc[3*MAXN],rc[3*MAXN],sz[3*MAXN],root,cnt;

struct Query{
    
int x,y,tag,k;
}query[
50001];
int ans[50001];


///////////////////////////////

int search(int t,int v);//返回下标

void insert(int &t,int v);//修改了树的结构,故参数需引用

int deletion(int &t,int v);//返回下标

int pred(int t,int v);//返回下标

int succ(int t,int v);//返回下标

int select(int t,int k);//返回下标

int rank(int t,int v);

//////////////////////////////


void RightRotate(int &t){
    
int k=lc[t];
    lc[t]
=rc[k];
    rc[k]
=t;
    sz[k]
=sz[t];
    sz[t]
=sz[lc[t]]+sz[rc[t]]+1;
    t
=k;
}

void LeftRotate(int &t){
    
int k=rc[t];
    rc[t]
=lc[k];
    lc[k]
=t;
    sz[k]
=sz[t];
    sz[t]
=sz[lc[t]]+sz[rc[t]]+1;
    t
=k;
}

int search(int t,int v){
    
if(!|| v==key[t])
        
return t;
    
if(v<key[t])
        
return search(lc[t],v);
    
else
        
return search(rc[t],v);
}

void Maintain(int &t,bool RightDeeper){//注意右旋的条件是左子树存在,左旋的条件是右子树存在
    if(!RightDeeper){
        
if(lc[t] && sz[lc[lc[t]]]>sz[rc[t]])
            RightRotate(t);
        
else if(lc[t] && rc[lc[t]] && sz[rc[lc[t]]]>sz[rc[t]]){
            LeftRotate(lc[t]);
            RightRotate(t);
        }
        
else
            
return;
    }
    
else{
        
if(rc[t] && sz[rc[rc[t]]]>sz[lc[t]])
            LeftRotate(t);
        
else if(rc[t] && lc[rc[t]] && sz[lc[rc[t]]]>sz[lc[t]]){
            RightRotate(rc[t]);
            LeftRotate(t);
        }
        
else
            
return;
    }
    Maintain(lc[t],
false);
    Maintain(rc[t],
true);
    Maintain(t,
false);
    Maintain(t,
true);
}

void insert(int &t,int v){
    
if(!t){
        
++cnt;
        t
=cnt;
        key[t]
=v;
        lc[t]
=0;
        rc[t]
=0;
        sz[t]
=1;
        
return;
    }
    sz[t]
++;
    
if(v<key[t])
        insert(lc[t],v);
    
else
        insert(rc[t],v);
    Maintain(t,v
>=key[t]);
}

int deletion(int &t, int v){//如果树中没有一个这样的结点,删除搜索到的最后一个结点并返回其指针  
    if(!t)
        
return 0;
    sz[t]
--;
    
if(v==key[t] || v<key[t]&&!lc[t] || v>key[t]&&!rc[t]){
        
int del;
        
if(!lc[t]||!rc[t]){
            del
=t;
            
//T=(T->lc?T->lc:T->rc);
            t=lc[t]+rc[t];
        }
        
else{//t有两个儿子
            del=deletion(rc[t],v-1);//v==key[t],记录t的后继并复制到t,删除后继
            key[t]=key[del];  //若有卫星数据也需复制
        }
        
return del;
    }
    
else return deletion(v<key[t]?lc[t]:rc[t],v);
}



int pred(int t,int v){
    
if(!t)
        
return 0;
    
if(v<=key[t])
        
return pred(rc[t],v);
    
else{
        
int p=pred(rc[t],v);
        
return (p?p:t);
    }
}

int succ(int t,int v){
    
if(!t)
        
return 0;
    
if(v>=key[t])
        
return succ(rc[t],v);
    
else{
        
int s=succ(lc[t],v);
        
return (s?s:t);
    }
}
 
int select(int t,int k){
    
if(!t||k>sz[t])
        
return 0;
    
int r=(lc[t]?sz[lc[t]]:0)+1;
    
if(k==r)
        
return t;
    
if(k<r)
        
return select(lc[t],k);
    
else
        
return select(rc[t],k-r);
}


int rank(int t,int v){
    
if(!t)
        
return 0;
    
if(v==key[t])
        
return (lc[t]?sz[lc[t]]:0)+1;
    
if(v<key[t])
        
return rank(lc[t],v);
    
else{
        
int r=rank(rc[t],v);
        
return r?r+(lc[t]?sz[lc[t]]:0)+1:0;
    }
}

class CP{
public:
    
int operator()(Query a,Query b){
        
if(a.x==b.x)
            
return a.y<b.y;
        
return a.x<b.x;
    }
};


int main(){
    
int i,j;
    
while(scanf("%d%d",&n,&m)!=EOF){
        
        
for(i=1;i<=n;i++)
            scanf(
"%d",&a[i]);
        
for(i=1;i<=m;i++){
            scanf(
"%d%d%d",&query[i].x,&query[i].y,&query[i].k);
            
if(query[i].x>query[i].y){
                
int temp=query[i].x;
                query[i].x
=query[i].y;
                query[i].y
=temp;
            }
            query[i].tag
=i;
        }
        sort(query
+1,query+m+1,CP());

        root
=cnt=0;
        
for(j=query[1].x;j<=query[1].y;j++)
            insert(root,a[j]);
        ans[query[
1].tag]=key[select(root,query[1].k)];
        
        
for(i=2;i<=m;i++){
            
if(query[i-1].y<query[i].x || query[i-1].x<query[i].x && query[i].y<query[i-1].y){
                root
=cnt=0;
                
//for(j=query[i-1].x;j<=query[i-1].y;j++)
                
//    deletion(root,a[j]);
                for(j=query[i].x;j<=query[i].y;j++)
                    insert(root,a[j]);
                
            }
            
else{
                
for(j=query[i-1].x;j<=query[i].x-1;j++)
                    deletion(root,a[j]);
                
for(j=query[i-1].y+1;j<=query[i].y;j++)
                    insert(root,a[j]);
            }
            ans[query[i].tag]
=key[select(root,query[i].k)];
            
        }
        
for(i=1;i<=m;i++)
            printf(
"%d\n",ans[i]);
    }
    
return 0;
}
posted @ 2008-11-15 01:20  Beetlebum  阅读(402)  评论(0编辑  收藏  举报