zoukankan      html  css  js  c++  java
  • P1533 可怜的狗狗

    漂亮小姐姐点击就送:https://www.luogu.org/problemnew/show/P1533

     

    题目背景

    小卡由于公务需要出差,将新家中的狗狗们托付给朋友嘉嘉,但是嘉嘉是一个很懒的人,他才没那么多时间帮小卡喂狗狗。

    题目描述

    小卡家有N只狗,由于品种、年龄不同,每一只狗都有一个不同的漂亮值。漂亮值与漂亮的程度成反比(漂亮值越低越漂亮),吃饭时,狗狗们会按顺序站成一排等着主人给食物。

    可是嘉嘉真的很懒,他才不肯喂这么多狗呢,这多浪费时间啊,于是他每次就只给第i只到第j只狗中第k漂亮的狗狗喂食(好狠心的人啊)。而且为了保证某一只狗狗不会被喂太多次,他喂的每个区间(i,j)不互相包含。

    输入输出格式

    输入格式:

    第一行输入两个数n,m,你可以假设n<300001 并且 m<50001;m表示他喂了m次。

    第二行n个整数,表示第i只狗的漂亮值为ai。

    接下来m行,每行3个整数i,j,k表示这次喂食喂第i到第j只狗中第k漂亮的狗的漂亮值。

    输出格式:

    M行,每行一个整数,表示每一次喂的那只狗漂亮值为多少。

    输入输出样例

    输入样例#1: 复制
    7 2
    1 5 2 6 3 7 4
    1 5 3
    2 7 1
    
    输出样例#1: 复制
    3
    2


    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<algorithm>
    using namespace std;
    
    const int N=3e5+5;
    const int INF=599518803;
    
    int n,m;
    int a[N];
    struct Query
    {
        int l,r,k,tim,ans;
    }query[N];
    struct Node
    {
        Node *son[2];
        int key;
        int key_cnt;
        int size;
        int heap_key;
    }node[N],A;
    
    typedef Node* Tree;
    Tree Root,now_node,null;
    
    bool cmp1(const Query &a,const Query &b)
    {
        return a.l<b.l;
    }
    
    bool cmp2(const Query &a,const Query &b)
    {
        return a.tim<b.tim;
    }
    
    void init()
    {
        srand(INF);
        node->son[0]=node->son[1]=node;
        Root=now_node=null=node;
    }
    
    inline Tree new_node(int key)
    {
        ++now_node;
        now_node->key=key;
        now_node->key_cnt=1;
        now_node->heap_key=rand();
        now_node->size=1;
        now_node->son[0]=now_node->son[1]=null;
        return now_node;
    }
    
    inline void rotate(Tree &root,bool flag)
    {
        Tree tmp=root->son[!flag];
        root->son[!flag]=tmp->son[flag];
        tmp->son[flag]=root;
        root->size=root->son[0]->size+root->son[1]->size+root->key_cnt;
        tmp->size=tmp->son[0]->size+tmp->son[1]->size+tmp->key_cnt;
        root=tmp;
    }
    
    void insert(Tree &root,int key)
    {
        if(root==null)
            root=new_node(key);
        else if(key==root->key)
            ++root->size,++root->key_cnt;
        else
        {
            bool flag=key>root->key;
            insert(root->son[flag],key);
            ++root->size;
            if(root->heap_key<root->son[flag]->heap_key)
                rotate(root,!flag);
        }
    }
    
    void erase(Tree &root,int key)
    {
        if(root==null)
            return;
        if(root->key!=key)
        {
            bool flag=key>root->key;
            erase(root->son[flag],key);
            --root->size;
        }
        else
        {
            if(root->key_cnt>1)
                --root->key_cnt,--root->size;
            if(root->son[0]==null)
                root=root->son[1];
            else if(root->son[1]==null)
                root=root->son[0];
            else
            {
                bool flag=root->son[0]->heap_key>root->son[1]->heap_key;
                rotate(root,flag);
                erase(root->son[flag],key);
                --root->size;
            }
        }
    }
    
    inline int kth(Tree root,int rank)
    {
        while(root!=null)
        {
            if(rank<=root->son[0]->size)
                root=root->son[0];
            else if(rank>root->son[0]->size+root->key_cnt)
                rank-=root->son[0]->size+root->key_cnt,root=root->son[1];
            else
                return root->key;
        }
    }
    
    int main()
    {
        //freopen("testdata.in","r",stdin);
        //freopen("233.out","w",stdout);
        init();
        scanf("%d%d",&n,&m);
        for(int i=1;i<=n;++i)
            scanf("%d",a+i);
        for(int i=1;i<=m;++i)
        {
            scanf("%d%d%d",&query[i].l,&query[i].r,&query[i].k);
    //        query[i].l=read(),
    //        query[i].r=read(),
    //        query[i].k=read(),
            query[i].tim=i;
        }
        sort(query+1,query+m+1,cmp1);
        for(int i=1;i<=m;++i)
        {
            if(i==1)
                for(int j=query[i].l;j<=query[i].r;++j)
                    insert(Root,a[j]);
            else
            {
                if(query[i-1].r<query[i].l)
                {
                    for(int j=query[i-1].l;j<=query[i-1].r;++j)
                        erase(Root,a[j]);
                }
                else
                {
                    for(int j=query[i-1].l;j<query[i].l;++j)
                        erase(Root,a[j]);
                }
                for(int j=query[i-1].r+1;j<=query[i].r;++j)
                    insert(Root,a[j]);
            }
            query[i].ans=kth(Root,query[i].k);
        }
        sort(query+1,query+m+1,cmp2);
        for(int i=1;i<=m;++i)
            printf("%d
    ",query[i].ans);
        return 0;
    }
    旋转 Treap
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<cstdio>
    #include<algorithm>
    using namespace std;
    
    const int N=300005;
    const int M=5e4+5;
    
    int n,m;
    int a[N];
    struct ASK
    {
        int l,r,k;
        int tim,ans;
    }ask[M];
    struct NODE
    {
        NODE *fa;
        NODE *son[2];
        int key,key_cnt;
        int size;
    }node[N];
    
    typedef NODE* Tree;
    Tree Root,now_node,null;
    
    inline int read()
    {
        char c=getchar();int num=0,f=1;
        for(;!isdigit(c);c=getchar())
            f=c=='-'?-1:f;
        for(;isdigit(c);c=getchar())
            num=num*10+c-'0';
        return num*f;
    }
    
    bool cmp1(const ASK &a,const ASK &b)
    {
        return a.l<b.l;
    }
    
    bool cmp2(const ASK &a,const ASK &b)
    {
        return a.tim<b.tim;
    }
    
    inline void init()
    {
        node->fa=node->son[0]=node->son[1]=node;
        Root=now_node=null=node;
    }
    
    inline Tree new_node(int key,Tree fa)
    {
        ++now_node;
        now_node->key=key;
        now_node->fa=fa;
        now_node->son[0]=now_node->son[1]=null;
        return now_node;
    }
    
    inline bool getgx(Tree root)
    {
        return root->fa->son[1]==root;
    }
    
    inline void connect(Tree root,Tree fa,bool flag)
    {
        if(fa==null)
            Root=root;
        else
            fa->son[flag]=root;
        if(root!=null)
            root->fa=fa;
    }
    
    inline void update(Tree root)
    {
        root->size=root->son[0]->size+root->son[1]->size+root->key_cnt;
    }
    
    inline void rotate(Tree root)
    {
        Tree fa=root->fa;
        Tree gfa=fa->fa;
        bool a=getgx(root),b=!a;
        connect(root->son[b],fa,a);
        connect(root,gfa,getgx(fa));
        connect(fa,root,b);
        update(fa);
        update(root);
    }
    
    inline void splay(Tree root,Tree goal)
    {
        while(root->fa!=goal)
        {
            Tree fa=root->fa;
            if(fa->fa==goal)
                rotate(root);
            else
            {
                if(getgx(root)==getgx(fa))
                    rotate(fa),rotate(root);
                else
                    rotate(root),rotate(root);
            }
        }
    }
    
    inline void insert(int key)
    {
        if(Root==null)
            Root=new_node(key,null);
        for(Tree root=Root;root!=null;root=root->son[key>root->key])
        {
            if(key==root->key)
            {
                ++root->key_cnt;
                ++root->size;
                splay(root,null);
                return;
            }
            else
                if(root->son[key>root->key]==null)
                    root->son[key>root->key]=new_node(key,root);
            ++root->size;
        }
    }
    
    inline void erase(int key)
    {
        if(Root==null)
            return;
        Tree root=Root;
        for(;root!=null&&root->key!=key;root=root->son[key>root->key]);
        if(root==null)
            return;
        splay(root,null);
        if(root->son[0]==null)
        {
            Root=root->son[1];
            if(Root!=null)
                Root->fa=null;
        }
        else
            if(root->son[1]==null)
            {
                Root=root->son[0];
                if(Root!=null)
                    Root->fa=null;
            }
        else
        {
            Tree tmp=root->son[0];
            for(;tmp->son[1]!=null;tmp=tmp->son[1]);
            splay(tmp,root);
            Root=tmp;
            Root->fa=null;
            Root->son[1]=root->son[1];
            if(Root->son[1]!=null)
                Root->son[1]->fa=Root;
            update(Root);
        }
    }
    
    inline int query(int rank)
    {
        for(Tree root=Root;root!=null;)
        {
            if(rank<=root->son[0]->size)
                root=root->son[0];
            else
                if(rank>root->son[0]->size+root->key_cnt)
                    rank-=root->son[0]->size+root->key_cnt,root=root->son[1];
            else
                return root->key;
        }
    }
    
    int main()
    {
    //    freopen("testdata.in","r",stdin);
        init();
        n=read(),m=read();
        for(int i=1;i<=n;++i)
            a[i]=read();
        for(int i=1;i<=m;++i)
        {
            ask[i].l=read(),ask[i].r=read(),ask[i].k=read();
            ask[i].tim=i;
        }
        sort(ask+1,ask+m+1,cmp1);
        int l=ask[1].l,r=l;
    
        for(int i=1;i<=m;++i)
        {
            for(;l<ask[i].l;++l)
                erase(a[l]);
            for(;r<=ask[i].r;++r)
                insert(a[r]);
            ask[i].ans=query(ask[i].k);
        }
        sort(ask+1,ask+m+1,cmp2);
        for(int i=1;i<=m;++i)
            printf("%d
    ",ask[i].ans);
        return 0;
    }
    Splay
  • 相关阅读:
    html+css实现简易下拉菜单
    Win10 设置外网多用户远程桌面连接
    ubuntu 14.04 下svn + apache2 配置
    JavaScript 学习笔记(一)
    生成Log文件的写法
    运行执行sql文件脚本的例子
    css实现文本框和下拉框结合的案例
    angularjs 1 开发简单案例(包含common.js,service.js,controller.js,page)
    将字符串转成只有首字母是大写
    java之springboot的spring-boot-starter-aop的切面编程的使用(四)
  • 原文地址:https://www.cnblogs.com/lovewhy/p/8670653.html
Copyright © 2011-2022 走看看