• Codeforces 38G Queue 伸展树


    题目链接:点击打开链接

    题意:

    给定n个人来排队

    每一个人有2个參数。身份优先级和脸皮厚度 ==

    来的那个人会排到队尾

    假设这个人的优先级比他前面那个人的优先级大就会和前面那个人交换位置。

    交换一次脸皮厚度减1, 一直交换到队头或者脸皮厚度为0

    交换完毕后下一个人才会到来。

    问:

    队伍最后的情况(从队头到队尾依次输出每一个人的编号)


    思路:splay

    维护子树的最小值。

    插入时递归插入,若当前点是空就插这个位置。

    然后就是裸的splay。。

    ==



    #include <stdio.h>
    #include <string.h>
    #include <stdlib.h>
    #include <math.h>
    #include <queue>
    #include <functional>
    #include <map>
    #include <iostream>
    #include <set>
    using namespace std;
    typedef pair<int,int> pii;
    #define ll int
    #define inf 1000000
    #define N 100005
    #define L(x) tree[x].ch[0]
    #define R(x) tree[x].ch[1]
    #define Size(x) tree[x].siz
    #define Val(x) tree[x].val
    #define Father(x) tree[x].fa
    #define Max(x) tree[x].max
    struct node{
        int ch[2], siz, fa;
        int val, max; //伸展树里存的是队列的顺序
    }tree[N];
    int tot, root;
    void Newnode(int &id, int fa, int val, int siz = 1){
        node E={0,0,siz,fa,val,val};
        id = tot++;
        tree[id] = E;
    }
    void push_down(int id){}
    void push_up(int id){
        Size(id) = Size(L(id)) + Size(R(id)) + 1;
        Max(id) = max( max(Max(L(id)), Max(R(id))), Val(id));
    }
    void Rotate(int id, int kind){
        int y = Father(id);
        push_down(y); push_down(id);
        tree[y].ch[kind^1] = tree[id].ch[kind];
        Father(tree[id].ch[kind]) = y;
        if(Father(y))
            tree[Father(y)].ch[R(Father(y))==y] = id;
        Father(id) = Father(y);
        Father(y) = id;
        tree[id].ch[kind] = y;
        push_up(y);
    }
    void Splay(int id, int goal){
        push_down(id);
        while(Father(id) != goal)
        {
            int y = Father(id);
            if(Father(y) == goal)
                Rotate(id, L(y) == id);
            else
            {
                int kind = L(Father(y)) == y;
                if(tree[y].ch[kind]==id)
                {
                    Rotate(id, kind^1);
                    Rotate(id, kind);
                }
                else
                {
                    Rotate(y, kind);
                    Rotate(id, kind);
                }
            }
        }
        push_up(id);
        if(goal == 0)root = id;
    }
    void Insert(int &id, int val, int siz, int father){ //把值为val的点插到goal点后面
    	if(id == 0) {
    		Newnode(id, father, val);
    		return ;
    	}
    	if(val < Max(R(id)) || val < Val(id) || siz < Size(R(id)))
    		Insert(R(id), val, siz, id);
    	else
    		Insert(L(id), val, siz-Size(R(id))-1, id);
    	push_up(id);
    }
    
    void init(){
        //初始化0这个点
        Father(0) = L(0) = R(0) = Size(0) = 0;
        Val(0) = 0;
        //默认1为最左端点
        tot = 1;
        Newnode(root, 0, inf);
        Newnode(R(root), root, -1);
        push_up(root);
    }
    map<int,int>mp;
    
    void put(ll id){
        if(L(id))
            put(L(id));
        if(id > 2)
            printf("%d ",mp[Val(id)]);
        if(R(id))
            put(R(id));
    }
    int main(){
        ll i, u, v, n, id;
        while(cin>>n){
            mp.clear();
            init();
            for(i = 1; i <= n; i++) {
                scanf("%d %d", &u, &v);
    			Insert(root, u, v, 0);
    			Splay(tot-1, 0);
                mp[u] = i;
            }
            put(root); puts("");
        }
        return 0;
    }
    /*
    2
    1 0
    2 1
    
    3
    1 3
    2 3
    3 3
    
    5
    2 3
    1 4
    4 3
    3 1
    5 2
    
    1
    1 0
    
    4
    4 1
    2 2
    1 3
    3 2
    
    4
    4 1
    2 2
    1 3
    3 1
    
    4
    4 1
    2 2
    1 3
    3 0
    
    4
    1 0
    2 1
    3 2
    4 3
    
    4
    1 0
    2 1
    4 2
    3 3
    
    5
    1 0
    2 1
    4 2
    3 3
    5 2
    
    6
    1 0
    2 1
    4 2
    3 3
    5 2
    6 4
    
    7
    2 2
    3 4
    5 1
    7 2
    6 5
    1 0
    4 1
    
    ans:
    1 4 2 3
    1 2 4 3
    1 2 3 4
    4 3 2 1
    3 4 2 1
    3 4 5 2 1
    3 6 4 5 2 1
    2 4 5 3 1 7 6
    
    */


  • 相关阅读:
    CSS:在input、pre中左边加上一个图标(一行和多行)
    IntelliJ IDEA 15 创建maven项目
    IntelliJ IDEA 15 部署Tomcat及创建一个简单的Web工程
    IntelliJ IDEA 15 安装
    IntelliJ IDEA 15 设置默认浏览器
    Eclipse 创建Maven工程
    Eclipse 安装热部署JRebel
    解决无法删除表,提示被外键约束引用
    MySql创建触发器
    WinServer2008r2 机器时间格式修改
  • 原文地址:https://www.cnblogs.com/liguangsunls/p/6772746.html
Copyright © 2020-2023  润新知