poj 2761 Feed the dogs treap

来源:互联网 发布:千牛卖家版mac不能用 编辑:程序博客网 时间:2024/05/01 19:16

   N个数,M个查询,每次查询L到R区间的第k小元素。可以用treap离线做..读取所有的查询,按左区间排序,由于数据保证不存在互相包涵的查询,所以相邻的两个区间要么相离,要么部分交叉。相离就依次删除上一次的元素,再一次插入本次的元素;交叉就删除上次不重叠的部分,然后把本次不重叠的部分插入。

#include <cstdio>#include <iostream>#include <cstring>#include <cmath>#include <algorithm>using namespace std;typedef long long ll;const int maxn=200000+1000;int ch[maxn][2],val[maxn],counts[maxn],r[maxn],size[maxn],tot,root;struct TREAP{    void newnode(int &rt,int v)    {        rt=++tot;        val[rt]=v;        ch[rt][0]=ch[rt][1]=0;        counts[rt]=size[rt]=1;        r[rt]=rand();    }    inline void pushup(int rt)    {        size[rt]=size[ch[rt][0]]+size[ch[rt][1]]+counts[rt];    }    void rotate(int &x,int kind)    {        int y=ch[x][kind^1];        ch[x][kind^1]=ch[y][kind];        ch[y][kind]=x;        pushup(x);        pushup(y);        x=y;    }    void insert(int &rt,int v)    {        if(rt==0)        {            newnode(rt,v);            return ;        }        if(v==val[rt]) counts[rt]++;        else        {            int kind=(v>val[rt]);            insert(ch[rt][kind],v);            if(r[ch[rt][kind]]<r[rt])                rotate(rt,kind^1);        }        pushup(rt);    }    int select(int rt,int k)    {        if(size[ch[rt][0]]>=k) return select(ch[rt][0],k);        if(size[ch[rt][0]]+counts[rt]>=k) return val[rt];        return select(ch[rt][1],k-size[ch[rt][0]]-counts[rt]);    }    void remove(int &rt,int v)    {        if(val[rt]==v)        {            if(counts[rt]>1)                counts[rt]--;            else if(!ch[rt][0]&&!ch[rt][1])            {rt=0;return ;}            else            {                int kind=r[ch[rt][0]]<r[ch[rt][1]];                rotate(rt,kind);                remove(rt,v);            }        }        else remove(ch[rt][v>val[rt]],v);        pushup(rt);    }    void init()    {        ch[0][0]=ch[0][1]=0;        size[0]=counts[0]=val[0]=0;        tot=root=0;        r[0]=(1LL<<31)-1;        newnode(root,2000000001);    }}treap;struct node{    int l,r,k,ans;    int id;}a[50500];bool cmp1(node p,node q){    if (p.l==q.l) return p.r<q.r;    return p.l<q.l;}bool cmp2(node p,node q){    return p.id<q.id;}int n,m,k;int num[maxn];int main(){//    freopen("in.txt","r",stdin);    while(~scanf("%d%d",&n,&m))    {        for (int i=1; i<=n; i++)        scanf("%d",&num[i]);        for (int i=0; i<m; i++)        scanf("%d%d%d",&a[i].l,&a[i].r,&a[i].k),a[i].id=i;        sort(a,a+m,cmp1);        treap.init();        int lastl=a[0].l,lastr=a[0].r;        for (int i=lastl; i<=lastr; i++)        treap.insert(root,num[i]);        a[0].ans=treap.select(root,a[0].k);        for (int i=1; i<m; i++)        {            if (a[i].l>lastr)            {                for (int j=lastl; j<=lastr; j++)                treap.remove(root,num[j]);                for (int j=a[i].l; j<=a[i].r; j++)                treap.insert(root,num[j]);            }            else            {                for (int j=lastl; j<a[i].l; j++)                treap.remove(root,num[j]);                for (int j=lastr+1; j<=a[i].r; j++)                treap.insert(root,num[j]);            }            a[i].ans=treap.select(root,a[i].k);            lastl=a[i].l;            lastr=a[i].r;        }        sort(a,a+m,cmp2);        for (int i=0; i<m; i++)        cout<<a[i].ans<<endl;    }    return 0;}


0 0
原创粉丝点击