您的位置:首页 > Web前端

pku2761 Feed the dogs

2008-11-15 01:20 281 查看
没什么好说的,和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(!t || 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;

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: