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;
}
#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;
}
相关文章推荐
- PKU 2761 Feed the dogs
- POJ(2761)Feed the dogs (树状数组+离散化+贪心)
- poj 2761 Feed the dogs 平衡树,线段树,树状数组
- 划分树学习笔记——NOJ[1458] Teemo,POJ2761——Feed the dogs
- poj 2761 Feed the dogs
- POJ2761--Feed the dogs
- POJ 2761 Feed the dogs (SBT+离线处理询问)
- poj 2761 Feed the dogs 离线treap
- 划分树 POJ 2761 feed the dogs
- POJ 2761-Feed the dogs(划分树)求区间内第k小的数
- POJ 2761 Feed the dogs 主席树(区间第k大)
- poj 2761 Feed the dogs (treap树)
- POJ - 2104 K-th Number && POJ 2761 Feed the dogs(主席树静态区间第k大)
- POJ 2761 Feed the dogs
- Feed the dogs POJ - 2761 (主席树第K大)
- [统计] poj 2761 Feed the dogs
- POJ-2761:Feed the dogs(划分树)
- POJ 2761 Feed the dogs(Treap求第K小数)
- [SBT]POJ 2761 Feed the dogs
- poj 2761 Feed the dogs 划分树