POJ 2761 (SBT模板)

来源:互联网 发布:mac唇釉价格 编辑:程序博客网 时间:2024/06/06 06:42
#include <iostream>#include <cstdio>#include <cstring>#include <algorithm>using namespace std;#define maxn 100005#define maxm 50005int ls[maxn],rs[maxn],s[maxn],value[maxn];int node,root;void init(){    node=root=s[0]=0;}void Right_Rotate(int &t){    int k=ls[t];    ls[t]=rs[k];    rs[k]=t;    s[k]=s[t];    s[t]=s[ls[t]]+s[rs[t]]+1;    t=k;}void Left_Rotate(int &t){    int k=rs[t];    rs[t]=ls[k];    ls[k]=t;    s[k]=s[t];    s[t]=s[ls[t]]+s[rs[t]]+1;    t=k;}void Maintain(int &t,bool flag){    if(flag)        if(s[rs[rs[t]]]>s[ls[t]])            Left_Rotate(t);        else if(s[ls[rs[t]]]>s[ls[t]])            Right_Rotate(rs[t]),Left_Rotate(t);        else return ;    else if(s[ls[ls[t]]]>s[rs[t]])        Right_Rotate(t);    else if(s[rs[ls[t]]]>s[rs[t]])        Left_Rotate(ls[t]),Right_Rotate(t);    else return ;    Maintain(ls[t],0);    Maintain(rs[t],1);    Maintain(t,0);    Maintain(t,1);}void Insert(int &t,int val)   //将键值为v的结点插入到根为t的树中{    if(t)    {        ++s[t];        if(val<value[t]) Insert(ls[t],val);        else Insert(rs[t],val);        Maintain(t,val>=value[t]);    }    else    {        s[t=++node]=1;        value[t]=val;        ls[t]=rs[t]=0;    }}int Delete(int &t,int val)   //在根为t的树中删除键值为v的结点{    --s[t];    if(val==value[t]||val<value[t]&&!ls[t]||val>value[t]&&!rs[t])    {        int tmp=value[t];        if(!ls[t]||!rs[t]) t=ls[t]+rs[t];        else value[t]=Delete(ls[t],value[t]+1);        return tmp;    }    else        if(val<value[t]) return Delete(ls[t],val);    else return Delete(rs[t],val);}int Pred(int t,int val) //返回根为t的树中比v小的最大的键值{    if(!t) return val;    if(val<=value[t]) return Pred(ls[t],val);    else    {        int tmp=Pred(rs[t],val);        return tmp==val?value[t]:tmp;    }}int Succ(int t,int val)  //返回根为t的树中比v大的最小的键值{    if(!t) return val;    if(val>=value[t]) return Succ(rs[t],val);    else    {        int tmp=Succ(ls[t],val);        return tmp==val?value[t]:tmp;    }}int Find(int t,int val)  //在根为t的树中查找键值为v的结点{    while(t&&val!=value[t])        t=val<value[t]?Find(ls[t],val):Find(rs[t],val);    return t;}int Rank(int t,int val)  //返回根为t的树中键值v的排名。也就是树中键值比v小的结点数+1{    if(!t) return 1;    if(val<=value[t]) return Rank(ls[t],val);    else return s[ls[t]]+1+Rank(rs[t],val);}int Select(int t,int k) //返回根为t的树中排名为k的结点。//同时该操作能够实现Get-min,Get-max,因为Get-min等于Select(t,1),Get-max等于Select(t,s[t]){    if(k==s[ls[t]]+1) return value[t];    if(k<=s[ls[t]]) return Select(ls[t],k);    else return Select(rs[t],k-1-s[ls[t]]);}void Debug(int t){    if(!t)    {        puts("empty!");        return ;    }    if(ls[t])        Debug(ls[t]);    printf("%d ",value[t]);    if(rs[t])        Debug(rs[t]);}struct qnode{    int l,r,k,id;    bool operator < (const qnode &tmp) const    {        return l<tmp.l;    }} q[maxm];int a[maxn],ans[maxm],mp[maxn];int main(){    int n,m;    scanf("%d%d",&n,&m);    init();    for(int i=1; i<=n; i++)        scanf("%d",a+i);    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);    q[0].l=0,q[0].r=0;    for(int i=1; i<=m; i++)    {        for(int j=q[i-1].l; j<=q[i-1].r&&j<q[i].l; j++)        if(j==0) continue;        else Delete(root,a[j]);        //Debug(root);        for(int j=q[i-1].r>=q[i].l?q[i-1].r+1:q[i].l; j<=q[i].r; j++)        {            Insert(root,a[j]);            //Debug(root);        }        ans[q[i].id]=Select(root,q[i].k);    }    for(int i=1; i<=m; i++)        printf("%d\n",ans[i]);    return 0;}


原创粉丝点击