您的位置:首页 > Web前端

POJ 2761 Feed the dogs Treap+离散处理

2016-06-21 17:56 260 查看
题目已说明任何两个区间不包含,也就是说对区间排序后的相邻两个区间L(i-1)<L(i) && R(i-1)<R(i)。那么离散化以后充分利用前后两个区间重叠的部分,多的去掉,少的补上。然后就是查询第k大了。



自己画了个图,对于第i个查询来说,红色部分就是重叠的部分不需要改,绿色部分是要从Treap中删掉的,蓝色部分是要再往Treap里加的。

吐个槽 : POJ中G++不支持INT_MAX

#include<iostream>
#include<cstdio>
#include<cstdlib>
#include<vector>
#include<cmath>
#include<string>
#include<algorithm>
#include<set>
#include<map>
#include<cstring>
#include<queue>
#include<stack>
#include<list>

using namespace std;

const int maxn=100000+100;
const int maxm=50000+200;
const int maxnode=maxn;

struct Treap{
int root,treapcnt,key[maxnode],priority[maxnode],
childs[maxnode][2],cnt[maxnode],size[maxnode];

void treap(){
root=0;
treapcnt=1;
priority[0]=2147483648-2;
size[0]=0;
}

void update(int x){
size[x]=size[ childs[x][0] ]+cnt[x]+size[ childs[x][1] ];
}

void rotate(int &x,int t){
int y=childs[x][t];
childs[x][t]=childs[y][1-t];
childs[y][1-t]=x;
update(x);
update(y);
x=y;
}

void __insert( int &x,int k ){
if(x){
if(key[x]==k){
cnt[x]++;
}
else{
int t=key[x]<k;
__insert(childs[x][t],k);
if( priority[childs[x][t]]<priority[x] ){
rotate(x,t);
}
}
}else{
x=treapcnt++;
key[x]=k;
cnt[x]=1;
priority[x]=rand();
childs[x][0]=childs[x][1]=0;
}
update(x);
}

void __erase(int &x,int k){
if(key[x]==k){
if(cnt[x]>1){
cnt[x]--;
}
else{
if(childs[x][0]==0&&childs[x][1]==0){
x=0;
return ;
}
int t=priority[ childs[x][0] ]>priority[childs[x][1]];
rotate(x,t);
__erase(x,k);
}
}else{
__erase(childs[x][key[x]<k],k);
}
update(x);
}

int __getkth(int &x,int k){
if(k<=size[childs[x][0]] ){
return __getkth(childs[x][0],k );
}
k-=size[childs[x][0]]+cnt[x];
if(k<=0)return key[x];
return __getkth(childs[x][1],k);
}

void insert( int k ){
__insert(root,k);
}

void erase(int k){
__erase(root,k);
}

int getkth(int k){
return __getkth(root,k);
}
};

struct query{
int l,r,k;
int id;
bool operator<(const query &b)const{
return l<b.l;
}
}qs[maxm];

Treap treap;
int a[maxn];
int ans[maxm];

int main()
{
int n,m;
while(scanf("%d%d",&n,&m)!=EOF){
treap.treap();
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
}
for(int i=0;i<m;i++){
scanf("%d%d%d",&qs[i].l,&qs[i].r,&qs[i].k);
qs[i].id=i;
}
sort(qs,qs+m);
for(int i=0;i<m;i++){
if(i==0){
for(int j=qs[i].l;j<=qs[i].r;j++){
treap.insert(a[j]);
}
}else{
for(int j=qs[i-1].l;j<qs[i].l;j++){
treap.erase(a[j]);
}
for(int j=qs[i-1].r+1;j<=qs[i].r;j++){
treap.insert(a[j]);
}
}
ans[qs[i].id]=treap.getkth(qs[i].k);
}
for(int i=0;i<m;i++){
printf("%d\n",ans[i]);
}

}

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