您的位置:首页 > Web前端

poj 2761 Feed the dogs SBT

2011-04-14 10:48 483 查看
Feed the dogs

查询一个区间上第k大的数,基本思路就是在sbt里只存要查询的区间上的数

先把要查询的区间按起点从小到大排序,这样就可以利用前一个区间上的数,i和i-1有重叠,那么就没有必要把i-1上的数全删除掉,这样可以快一点

我开始就没管直接全部删除,然后把i上的数全部插入结果毫无悬念超时。。。

/*
* File:   main.cpp
* Author: Mi
*
* Created on 2011年4月14日, 上午9:22
*/
#include <cstdlib>
#include <stdio.h>
#include <string.h>
#include <algorithm>
#define N 100005
using namespace std;
/*
*
*/
int tol,v
;
struct node
{
int s,e,k,id,ans;
}q
;
struct SBT
{
int left,right;
int size;
int key;
void init()
{
left=right=0;
size=1;
}
}T
;
void R_Rotate(int &t)
{
int k=T[t].left;
T[t].left=T[k].right;
T[k].right=t;
T[k].size=T[t].size;
T[t].size=T[T[t].left].size+T[T[t].right].size+1;
t=k;
return ;
}
void L_Rotate(int &t)
{
int k=T[t].right;
T[t].right=T[k].left;
T[k].left=t;
T[k].size=T[t].size;
T[t].size=T[T[t].left].size+T[T[t].right].size+1;
t=k;
return ;
}
void Maintain(int &t,bool flag)
{
if(flag==false)
{
if(T[T[T[t].left].left].size>T[T[t].right].size)
R_Rotate(t);
else if(T[T[T[t].left].right].size>T[T[t].right].size)
{
L_Rotate(T[t].left);
R_Rotate(t);
}
else
return ;
}
else
{
if(T[T[T[t].right].right].size>T[T[t].left].size)
L_Rotate(t);
else if(T[T[T[t].right].left].size>T[T[t].left].size)
{
R_Rotate(T[t].right);
L_Rotate(t);
}
else
return ;
}
Maintain(T[t].left,false);
Maintain(T[t].right,true);
Maintain(t,false);
Maintain(t,true);
}
void Insert(int &t,int v)
{
if(t==0)
{
t=++tol;
T[t].init();
T[t].key=v;
}
else
{
T[t].size++;
if(v<T[t].key)
Insert(T[t].left,v);
else
Insert(T[t].right,v);
Maintain(t,v>=T[t].key);
}
}
int Delete(int &t,int v)
{
if(!t)
return 0;
T[t].size--;
if(v==T[t].key||v<T[t].key&&!T[t].left||v>T[t].key&&!T[t].right)
{
if(T[t].left&&T[t].right)
{
int p=Delete(T[t].left,v+1);
T[t].key=T[p].key;
return p;
}
else
{
int p=t;
t=T[t].left+T[t].right;
return p;
}
}
else
return Delete(v<T[t].key?T[t].left:T[t].right,v);
}
int Find_k(int t,int k)
{
if(k<=T[T[t].left].size)
return Find_k(T[t].left,k);
else if(k>T[T[t].left].size+1)
return Find_k(T[t].right,k-T[T[t].left].size-1);
else
return T[t].key;
}
bool cmp(node x,node y)
{
if(x.s==y.s)
return x.e<y.e;
return x.s<y.s;
}
bool cmp1(node x,node y)
{
return x.id<y.id;
}
int main(int argc, char** argv)
{
tol=0;
int root=0;
int n,m;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++)
scanf("%d",&v[i]);
for(int i=0;i<m;i++)
{
scanf("%d%d%d",&q[i].s,&q[i].e,&q[i].k);
q[i].id=i;
}
sort(q,q+m,cmp);
for(int i=q[0].s;i<=q[0].e;i++)
Insert(root,v[i]);
q[0].ans=Find_k(root,q[0].k);
for(int i=1;i<m;i++)
{
if(q[i].s>=q[i-1].e)
{
for(int j=q[i-1].s;j<=q[i-1].e;j++)
Delete(root,v[j]);
for(int j=q[i].s;j<=q[i].e;j++)
Insert(root,v[j]);
}
else if(q[i].s<=q[i-1].e&&q[i].e>q[i-1].e)
{
for(int j=q[i-1].s;j<q[i].s;j++)
Delete(root,v[j]);
for(int j=q[i-1].e+1;j<=q[i].e;j++)
Insert(root,v[j]);
}
q[i].ans=Find_k(root,q[i].k);
}
sort(q,q+m,cmp1);
for(int i=0;i<m;i++)
printf("%d/n",q[i].ans);
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: