zoukankan      html  css  js  c++  java
  • COGS2421 [HZOI 2016]简单的Treap

     

    题面见这里

    大概是个模板题

    Treap暴力插入的做法太暴力了并不优美

    这里就需要用到笛卡尔树的构造方法,定义见这里

    在 假的O(n) 的时间内构造一棵Treap

    把元素从小到大排序

    这样从小到大插入时,只会往树上最右边的链上走

    这样考虑一下 Treap 正常的 Insert 的过程:

      只要找到第一个优先级更小(大根堆)的节点,将待插入节点插到上一层的右儿子的位置

      将当前找到的节点作为待插入节点的左儿子

    这样就类似一个旋转操作,也就成功的模拟实现出了一个的 Treap 完整的 Insert 的过程

    具体在代码里是这样的:

      用一个单调栈维护整个树的最右边的链

      边找符合要求的节点边出栈

      找到之后进行上面提到的操作即可

    #include<algorithm>
    #include<iostream>
    #include<cstdlib>
    #include<cstring>
    #include<cctype>
    #include<cstdio>
    #include<stack>
    using namespace std;
    
    const int MAXN = 500001;
    
    struct Node{
    	int ch[2], val, prio;
    	Node(){ch[0] = ch[1] = val = 0;}
    	bool operator < (const Node &b) const{
    		return val < b.val;
    	}
    }t[MAXN];
    int n, top, stk[MAXN];
    
    inline int rd() {
    	register int x = 0;
    	register char c = getchar();
    	register bool f = false;
    	while(!isdigit(c)) {
    		if(c == '-') f = true;
    		c = getchar();
    	}
    	while(isdigit(c)) {
    		x = x * 10 + (c ^ 48);
    		c = getchar();
    	}
    	return f ? -x : x;
    }
    stack<int> dfs;
    bool vis[MAXN];
    void Recycle() {
    	dfs.push(stk[1]);
    	vis[0] = true;
    	while(dfs.size()) {
    		int cur = dfs.top();
    		if(!vis[cur]) {
    			vis[cur] = true;
    			printf("%d ", t[cur].val);
    		}
    		if(!vis[t[cur].ch[0]]) dfs.push(t[cur].ch[0]);
    		else if(!vis[t[cur].ch[1]]) dfs.push(t[cur].ch[1]);
    		else dfs.pop();
    	}
    	return;
    }
    
    int main() {
    	freopen("treap.in", "r", stdin);
    	freopen("treap.out", "w", stdout);
    	n = rd();
    	for(int i = 1; i <= n; ++i) t[i].val = rd();
    	for(int i = 1; i <= n; ++i) t[i].prio = rd();
    	sort(t + 1, t + n + 1);
    	stk[++top] = 1;
    	for(int i = 2; i <= n; ++i) {
    		int last = 0;
    		while(top and t[stk[top]].prio > t[i].prio) last = stk[top--];
    		t[i].ch[0] = last;
    		if(top) t[stk[top]].ch[1] = i;
    		stk[++top] = i;
    	}
    	//printf("root %d
    ", stk[1]);
    	Recycle();
    	fclose(stdin);
    	fclose(stdout);
    	return 0;
    }
    

      


    禁止诸如开发者知识库/布布扣/码迷/学步园/马开东等 copy 他人博文乃至博客的网站转载 ,用户转载请注明出处:https://www.cnblogs.com/xcysblog/
  • 相关阅读:
    excel
    AWS学习之EC2
    约瑟夫问题
    centos7 系統vps安裝mysql5.6及設置本地遠程連接筆記
    搜索框的测试checklist
    产品把整个项目组拉走去创业,这是什么神操作
    python基础-python函数参数为print语句时的输出
    python基础学习笔记-切片难点
    session 、cookie、token的区别(转)
    robot framework python3环境下学习笔记(1)——安装robot framework
  • 原文地址:https://www.cnblogs.com/xcysblog/p/9079019.html
Copyright © 2011-2022 走看看