poj 2761 Feed the dogs(treap+离线)

来源:互联网 发布:js splice slice 编辑:程序博客网 时间:2024/05/16 23:58

题目链接:http://poj.org/problem?id=2761

思路:求区间第k小的树,题目中有一个关键的条件即没有一个区间能够包含另外一个区间,也就是说如果[ai,bi],[aj,bj]两个区间如果ai<aj那么bi<bj。做离线处理,将区间保存,并按照区间起始和终止位置排序,需要记录区间原始编号。然后按照区间的要求向treap中插入删除节点。

#include<cstdio>#include<cstring>#include<algorithm>using namespace std;const int N=50005;struct seg{    int st,en,kth,id,ans;}d[N];int data[N*2],e,n,m,root,ans;struct node{    int l,r,val,siz,pri;}a[N*2];bool cmp(const seg a,const seg b){    if(a.en!=b.en)        return a.en<b.en;    return a.st<b.st;}bool cmp1(const seg a,const seg b){    return a.id<b.id;}int Newnode(int val){    int x=e++;    a[x].val=val;    a[x].siz=1;    a[x].l=a[x].r=-1;    a[x].pri=rand();    return x;}void pushup(int k){    if(k==-1) return ;    a[k].siz=1;    if(a[k].l!=-1)        a[k].siz+=a[a[k].l].siz;    if(a[k].r!=-1)        a[k].siz+=a[a[k].r].siz;}void rotl(int &x){    int y=a[x].r;    a[x].r=a[y].l;    a[y].l=x;    pushup(x);    pushup(y);    x=y;}void rotr(int &x){    int y=a[x].l;    a[x].l=a[y].r;    a[y].r=x;    pushup(x);    pushup(y);    x=y;}void insert(int &k,int val){    if(k==-1)        k=Newnode(val);    else if(val<a[k].val)    {        insert(a[k].l,val);        if(a[a[k].l].pri>a[k].pri) rotr(k);    }    else    {        insert(a[k].r,val);        if(a[a[k].r].pri>a[k].pri) rotl(k);    }    pushup(k);}void del(int &k,int val){    if(k==-1)        return ;    else if(val<a[k].val)        del(a[k].l,val);    else if(val>a[k].val)        del(a[k].r,val);    else    {        if(a[k].l==-1&&a[k].r==-1) k=-1;        else if(a[k].l==-1)            k=a[k].r;        else if(a[k].r==-1)            k=a[k].l;        else        {            if(a[a[k].l].pri<a[a[k].r].pri)            {                rotl(k);                del(a[k].l,val);            }            else            {                rotr(k);                del(a[k].r,val);            }        }    }    pushup(k);}void query(int k,int x){    int siz;    if(a[k].l==-1)        siz=0;    else        siz=a[a[k].l].siz;    if(siz+1==x)    {        ans=a[k].val;        return ;    }    else if(x<=siz)        query(a[k].l,x);    else        query(a[k].r,x-siz-1);}void output(int k){    if(k==-1)        return ;    printf("k=%d val=%d siz=%d\n",k,a[k].val,a[k].siz);    if(a[k].l!=-1)        output(a[k].l);    if(a[k].r!=-1)        output(a[k].r);}int main(){    int i,a,b,c,p,q,cnt;    //freopen("in.txt","r",stdin);    while(scanf("%d%d",&n,&m)!=EOF)    {        for(i=0;i<n;i++)            scanf("%d",&data[i]);        for(i=0;i<m;i++)        {            scanf("%d %d %d",&a,&b,&c);            d[i].st=a-1;            d[i].en=b-1;            d[i].kth=c;            d[i].id=i;        }        e=0;        sort(d,d+m,cmp);        root=-1;//注为-1        p=0;        q=0;        cnt=0;        while(cnt<m)        {            while(q<=d[cnt].en)            {                insert(root,data[q]);                q++;            }            while(p<d[cnt].st)            {                del(root,data[p]);                p++;            }            query(root,d[cnt].kth);            d[cnt].ans=ans;            cnt++;            //output(root);            //printf("\n");        }        sort(d,d+m,cmp1);        for(i=0;i<m;i++)            printf("%d\n",d[i].ans);    }    return 0;}


0 0
原创粉丝点击
热门问题 老师的惩罚 人脸识别 我在镇武司摸鱼那些年 重生之率土为王 我在大康的咸鱼生活 盘龙之生命进化 天生仙种 凡人之先天五行 春回大明朝 姑娘不必设防,我是瞎子 江苏低于二本线怎么办 电工证快过期了怎么办 天正建筑打不开高版本的图纸怎么办 打开天正只显示cad怎么办 天正软件显示过期了怎么办 四岁宝宝经常吐怎么办 穿越火线登陆不上去怎么办 猫猫呕吐带血怎么办 狗又吐又拉稀怎么办 狗狗肠炎拉血怎么办 拉大便有血怎么办呢 工作中遇到不公待遇怎么办 老兵丢了退伍证怎么办 我的退伍证丢了怎么办 退伍证丢了怎么办啊 银行卡更换之前的卡号怎么办 收到联通欠费催款律师函怎么办 苹果5s玩王者卡怎么办 电信宽带包年用户欠费怎么办 员工不处理考勤异常怎么办 移动号码特殊原因强制停机怎么办 下雨天我怎么办我好想你 免检标志领晚了怎么办 激光点太田痣揉搓了泛红怎么办 花束与衣服颜色相称怎么办 吃鸡狙击枪距离怎么办 环世界敌人炸墙怎么办 水阀断在墙里面怎么办 内陷螺丝扣秃了怎么办 五菱仪表盘不亮怎么办 瞒着老婆欠了钱怎么办 m8螺丝牙距孔距差一个毫米怎么办 内丝弯头坏了怎么办 螺纹底孔打大了怎么办 内螺纹止规过了怎么办 牌照螺丝装错了怎么办 帽式扳手大了怎么办 内六角扳手小了怎么办 内六角扳手不够大怎么办? 苹果6螺丝拧花了怎么办 苹果电脑螺丝拧花了怎么办