poj 2761 treap

来源:互联网 发布:淘宝汽车坐垫四季通用 编辑:程序博客网 时间:2024/06/07 10:34

利用区间的有序性才可以用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 111111using 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 111111using 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;}



原创粉丝点击