您的位置:首页 > 其它

【POJ】【P2104&P2761】【题解】【区间K大】【主席树】

2014-05-04 10:22 211 查看
传送门:

http://poj.org/problem?id=2104

http://poj.org/problem?id=2761

裸主席树……

Code:

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1e5+10;
int a[maxn],b[maxn];
struct node{
int size;
node *c[2];
node(){
c[0]=c[1]=NULL;size=0;
}
void rz(){
if(c[0])size+=c[0]->size;
if(c[1])size+=c[1]->size;
}
}*Null=new node(),*root[maxn]={NULL};
int tot;
node poor[maxn<<4];
void insert(node *&y,node *&x,int l,int r,int t){
if(x==NULL)x=Null;

if(tot<(maxn<<4)){
y=&poor[tot++];
y->c[0]=y->c[1]=Null;
y->size=0;
}else
y=new node();

int mid=(l+r)>>1;
if(l==r){
*y=*x;
y->size++;
return;
}
if(t<=b[mid]){
insert(y->c[0],x->c[0],l,mid,t);
y->c[1]=x->c[1];
y->rz();
}else{
insert(y->c[1],x->c[1],mid+1,r,t);
y->c[0]=x->c[0];
y->rz();
}
}
int kth(node *&x,node *&y,int l,int r,int k){
if(x==NULL)x=Null;
if(y==NULL)y=Null;
if(l==r)return b[l];
int mid=(l+r)>>1;
int R=0;
if(y->c[0])R+=y->c[0]->size;
if(x->c[0])R-=x->c[0]->size;
if(R>=k)return kth(x->c[0],y->c[0],l,mid,k);
else return kth(x->c[1],y->c[1],mid+1,r,k-R);
}
int n,m,size;
int main(){
Null->c[0]=Null->c[1]=Null;
scanf("%d%d",&n,&m);
for(int i=1;i<=n;i++){
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+1+n);
size=unique(b+1,b+1+n)-b-1;
for(int i=1;i<=n;i++)
insert(root[i],root[i-1],1,size,a[i]);
while(m--){
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",kth(root[l-1],root[r],1,size,k));
}
return 0;
}


新模版:

#include<cstdio>
#include<iostream>
#include<algorithm>
using namespace std;
const int maxn=1e5+10;
inline int lowbit(int x){
return x&(-x);
}
struct node{
int size;
node *c[2];
node();
void rz(){
size=c[0]->size+c[1]->size;
}
}*Null=new node(),*root[maxn];
node poor[maxn<<4];
int tot;
node::node(){
size=0;
c[0]=c[1]=Null;
}
int a[maxn],b[maxn];
void insert(node *&y,node *&x,int l,int r,int t){
//if(x==NULL)x=Null;
if(tot<(maxn<<4)){
y=&poor[tot++];
y->size=0;y->c[0]=y->c[1]=Null;
}else y=new node();
if(l==r){
*y=*x;y->size++;return;
}
int mid=(l+r)>>1;
if(t<=b[mid]){
insert(y->c[0],x->c[0],l,mid,t);
y->c[1]=x->c[1];
y->rz();
}else{
insert(y->c[1],x->c[1],mid+1,r,t);
y->c[0]=x->c[0];
y->rz();
}
}
int kth(node *&x,node *&y,int l,int r,int k){
if(l==r)return b[l];
int mid=(l+r)>>1;
int R=y->c[0]->size-x->c[0]->size;
if(R>=k)return kth(x->c[0],y->c[0],l,mid,k);
else return kth(x->c[1],y->c[1],mid+1,r,k-R);
}
int n,m,size;
int main(){
Null->size=0;
Null->c[0]=Null->c[1]=Null;
scanf("%d%d",&n,&m);
root[0]=Null;
for(int i=1;i<=n;i++){
root[i]=Null;
scanf("%d",&a[i]);
b[i]=a[i];
}
sort(b+1,b+1+n);
size=unique(b+1,b+1+n)-b-1;
for(int i=1;i<=n;i++)
insert(root[i],root[i-1],1,size,a[i]);
while(m--){
int l,r,k;
scanf("%d%d%d",&l,&r,&k);
printf("%d\n",kth(root[l-1],root[r],1,size,k));
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  bzoj 省选