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

你可能感兴趣的:(pku)