poj 2761 treap

利用区间的有序性才可以用treap 其实这题 线段树和树状数组时更好的选择 稍后补上

#include<cstdio>
#include<cstdlib>
#include<cmath>
#include<iostream>
using namespace std;
const int inf=~0U>>1;
class treap
{
    struct node
    {
        int val,key,size;
        node *c[2];
        node(int v,node *x){val=v,c[0]=c[1]=x,size=1;key=rand()-1;}
        void rz(){size=c[0]->size+c[1]->size+1;}
    }*root,*null;
    void ro(node *&x,bool d)
    {
        node *t=x->c[d];
        x->c[d]=t->c[!d];
        t->c[!d]=x;
        x->rz();t->rz();x=t;
    }
    void insert(node *&x,int v)
    {
        if(x==null) {x=new node(v,null);return;}
       // if(x->val==v) return ;
        bool d=(v>=x->val);
        insert(x->c[d],v);
        if(x->c[d]->key<x->key)
        ro(x,d); else x->rz();
    }
    void dele(node*&x,int v)
    {
        if(x==null) return ;
        if(x->val==v)
        {
            bool d=x->c[0]->key>x->c[1]->key;
            if(x->c[d]==null)
            {
                x=null;
                return ;
            }
           ro(x,d);
           dele(x->c[!d],v);
        }
       else
       {
           bool d=v>x->val;
           dele(x->c[d],v);
       }
       x->rz();
    }
    int select(node *x,int k)
    {
        if(x->c[0]->size==k) return x->val;
        else  if(x->c[0]->size>k) return select(x->c[0],k);
        else return select(x->c[1],k-x->c[0]->size-1);
    }
    int ran(node *x,int v)
    {
        if(x==null) return 0;
        if(x->val==v) return x->c[0]->size;
        if(x->val>v) return ran(x->c[0],v);
        else return ran(x->c[1],v)+1+x->c[0]->size;
    }
    void pr(node *x) {if(x!=null) {pr(x->c[0]);cout<<x->val<<" ";pr(x->c[1]);}}
    public:
    treap(){null=new node(0,0);null->size=0;null->key=inf;root=null;}
    void ins(int v){insert(root,v);}
    void del(int v){dele(root,v);}
    int rank(int v){return ran(root,v);}
    int find_k(int k){if(root->size<k) return -inf;return select(root,k-1);}
    void pr(){pr(root);puts("");}
};
int n,m;
int val[111111];
struct query
{
    int l,r,id,k;
    bool operator <(query q)
    {
        return l<q.l||(l==q.l&&r<q.r);
    }
}a[55555];
int ans[55555];
template <class T>
void quicksort(T *p,int s,int e)
{
    if(s<e)
    {
        int i=s,j=e;T tmp=p[e];
        while(i<j)
        {
            while(i<j&&p[i]<tmp) ++i;
            if(i<j) p[j--]=p[i];
            while(i<j&&tmp<p[j]) --j;
            if(i<j) p[i++]=p[j];
        }
        p[i]=tmp;
        quicksort(p,s,i-1);
        quicksort(p,i+1,e);
    }
}
int main()
{
  while(scanf("%d%d",&n,&m)==2)
  {
      treap T;
      for(int i=1;i<=n;++i)
     {
         scanf("%d",val+i);
     }
     for(int i=1;i<=m;++i)
   {
       scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].k);
       a[i].id=i;
   }
  quicksort(a,1,m);
for(int i=1;i<=m;++i)
{
    //cout<<a[i].l<<" "<<a[i].r<<" "<<a[i].k<<" "<<a[i].id;
   int  d=(a[i-1].r<a[i].l-1)?a[i-1].r:a[i].l-1;
   int in=(a[i-1].r+1>a[i].l)?a[i-1].r+1:a[i].l;
//   cout<<" "<<d<<" "<<in<<endl;
 if(i>1)  for(int j=a[i-1].l;j<=d;++j)
   T.del(val[j]);
   for(int j=in;j<=a[i].r;++j)
   T.ins(val[j]);
   ans[a[i].id]=T.find_k(a[i].k);
  // T.pr();
}
for(int i=1;i<=m;++i)
printf("%d\n",ans[i]);
  }
    return 0;
}


我次奥 换成系统的sort 直接变成 3000ms


线段树版本

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define N 111111
using namespace std;
int sum[N<<2];
void pup(int rt)
{
    sum[rt]=sum[rt<<1]+sum[rt<<1|1];
}
void update(int p,int add,int l,int r,int rt)
{
    if(l==r)
    {
        sum[rt]+=add;
        return;
    }
    int mid=(l+r)>>1;
    if(p<=mid) update(p,add,lson);
    else update(p,add,rson);
    pup(rt);
}
int  que(int k,int l,int r,int rt)
{
    if(l==r) return l;
    int mid=(l+r)>>1;
    if(k<=sum[rt<<1])
    return que(k,lson);
    else
    return que(k-sum[rt<<1],rson);
}
struct ps
{
    int id,val;
}a[111111];
int va[111111];
int cmp(ps p,ps q){return p.val<q.val;}
int n,m;
struct pp
{
    int l,r,id,k;
}q[55555];
int cmp2(pp p,pp q){return p.l<q.l;}
int ans[55555];
int main()
{
    while(scanf("%d%d",&n,&m)==2)
    {
        for(int i=1;i<=n;++i)
        {
            scanf("%d",&a[i].val);
            a[i].id=i;
        }
        sort(a+1,a+1+n,cmp);
        for(int i=1;i<=n;++i)
        va[a[i].id]=i;
        memset(sum,0,sizeof(sum));
        for(int i=1;i<=m;++i)
        {
            scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].k);
            q[i].id=i;
        }
        sort(q+1,q+1+m,cmp2);
        for(int i=q[1].l;i<=q[1].r;++i)
        update(va[i],1,1,n,1);
        ans[q[1].id]=que(q[1].k,1,n,1);
        for(int i=2;i<=m;++i)
        {
            int d,in;
            d=(q[i-1].r<q[i].l-1)?q[i-1].r:q[i].l-1;
            in=(q[i-1].r+1<q[i].l)?q[i].l:q[i-1].r+1;
           for(int j=q[i-1].l;j<=d;++j)
           update(va[j],-1,1,n,1);
           for(int j=in;j<=q[i].r;++j)
           update(va[j],1,1,n,1);
           ans[q[i].id]=que(q[i].k,1,n,1);
        }
        for(int i=1;i<=m;++i)
        printf("%d\n",a[ans[i]].val);
    }
    return 0;
}


下面是树状数组

#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#define N 111111
using namespace std;
int sum[N];
struct ps
{
    int id,val;
}a[111111];
int va[111111];
int cmp(ps p,ps q){return p.val<q.val;}
int n,m;
struct pp
{
    int l,r,id,k;
}q[55555];
int cmp2(pp p,pp q){return p.l<q.l;}
int ans[55555];
int lowbit(int x){return x&(x^(x-1));}
void update(int p,int add)
{
   for(;p<=n;p+=lowbit(p))
   sum[p]+=add;
}
int qu(int p)
{
    int res;
    for(res=0;p;p-=lowbit(p))
    res+=sum[p];
    return res;
}
int  que(int k)
{
   int l=1,r=n,mid;
   for(;l<=r;)
   {
       mid=(l+r)>>1;
       int res=qu(mid);
        if(res>=k) r=mid-1;
       else l=mid+1;
   }
   return l;
}
int main()
{
    while(scanf("%d%d",&n,&m)==2)
    {
        for(int i=1;i<=n;++i)
        {
            scanf("%d",&a[i].val);
            a[i].id=i;
        }
        sort(a+1,a+1+n,cmp);
        for(int i=1;i<=n;++i)
        va[a[i].id]=i;
        memset(sum,0,sizeof(sum));
        for(int i=1;i<=m;++i)
        {
            scanf("%d%d%d",&q[i].l,&q[i].r,&q[i].k);
            q[i].id=i;
        }
        sort(q+1,q+1+m,cmp2);
        for(int i=q[1].l;i<=q[1].r;++i)
        update(va[i],1);
        ans[q[1].id]=que(q[1].k);
        for(int i=2;i<=m;++i)
        {
            int d,in;
            d=(q[i-1].r<q[i].l-1)?q[i-1].r:q[i].l-1;
            in=(q[i-1].r+1<q[i].l)?q[i].l:q[i-1].r+1;
           for(int j=q[i-1].l;j<=d;++j)
           update(va[j],-1);
           for(int j=in;j<=q[i].r;++j)
           update(va[j],1);
           ans[q[i].id]=que(q[i].k);
        }
        for(int i=1;i<=m;++i)
        printf("%d\n",a[ans[i]].val);
    }
    return 0;
}



你可能感兴趣的:(poj 2761 treap)