zoukankan      html  css  js  c++  java
  • 数据结构水题大赛官方题解#3 XXX的stl

    数据结构水题大赛 T3

    XXX的stl

    题面

    洛谷链接

    题解

    本题要求查询一个数组最大值, 插入一个数字, 随机删除一个元素. 有(20')的暴力得分, (20')的priority_queue得分, 正解是手打大根堆

    20'暴力

    这个不用说了, 直接几层循环套娃就能过

    20'stl

    往priority_queue里插入元素, 查询时直接返回q.top

    100'手写大根堆

    大根堆很好处理, 查询是直接返回根节点, 但是由于删除是按照下标 (插入顺序) 检索的, 所以在存入大根堆的同时还要捆绑一个下标.

    由于知道了下标不一定知道在大根堆里的位置, 所以还要维护一个数组Num[]通过下标定位到大根堆中的位置.

    由于随机删除会减少大根堆元素数量, 但是下标不会减少, 所以需要两个cnt变量, 一个存实际的元素数量, 用于维护插入元素的位置, 另一个存累计元素数量, 来为新元素分配下标.

    AC代码

    #include <algorithm>
    #include <cmath>
    #include <cstdio>
    #include <cstdlib>
    #include <cstring>
    #include <ctime>
    #include <iostream>
    #include <map>
    #include <queue>
    #include <vector>
    using namespace std;
    int t, n, m, a[400005], ans = 0, cnt = 0, cnt1 = 0, Dui[400005][2], Do, Num[400005];
    bool flg;
    char ch;
    string s;
    inline int IN() {
    	char ich = getchar();
    	int intmp = 0, insign = 1;
    	while (((ich < '0') || (ich > '9')) && ((ich != '-'))) {
    		ich = getchar();
    	}
    	if (ich == '-') {
    		insign = -1;
    		ich = getchar();
    	}
    	while ((ich <= '9') && (ich >= '0')) {
    		intmp *= 10;
    		intmp += ich - '0';
    		ich = getchar();
    	}
    	return intmp * insign;
    }
    void Add (int x) {
    	cnt++;
    	cnt1++;
    	Num[cnt] = cnt;
    	Dui[cnt][0] = x;
    	Dui[cnt][1] = cnt1;
    	int now = cnt;
    	while (Dui[now][0] > Dui[now >> 1][0]) {
    		swap(Dui[now][0], Dui[now >> 1][0]);
    		swap(Dui[now][1], Dui[now >> 1][1]);
    		Num[Dui[now][1]] = now;
    		Num[Dui[now >> 1][1]] = now >> 1;
    		now = now >> 1;
    	}
    	return;
    }
    void Del(int x) {
    	if(Num[x] == 0) {
    		return;
    	}
    	int now = Num[x];
    	Num[x] = 0; 
    	Dui[now][0] = Dui[cnt][0];
    	Dui[now][1] = Dui[cnt][1];
    	cnt--;
    	while (Dui[now][0] < max(Dui[now << 1][0], Dui[(now << 1) + 1][0])) {
    		if(Dui[now << 1][0] <= Dui[(now << 1) + 1][0]){
    			swap(Dui[now][0], Dui[(now << 1) + 1][0]);
    			swap(Dui[now][1], Dui[(now << 1) + 1][1]);
    			Num[Dui[now][1]] = now;
    			Num[Dui[(now << 1) + 1][1]] = (now << 1) + 1;
    			now = (now << 1) + 1;
    		}
    		else {
    			swap(Dui[now][0], Dui[now << 1][0]);
    			swap(Dui[now][1], Dui[now << 1][1]);
    			Num[Dui[now][1]] = now;
    			Num[Dui[now << 1][1]] = now << 1;
    			now = now << 1;
    		}
    	}
    	while (Dui[now][0] > Dui[now >> 1][0]) {
    		swap(Dui[now][0], Dui[now >> 1][0]);
    		swap(Dui[now][1], Dui[now >> 1][1]);
    		Num[Dui[now][1]] = now;
    		Num[Dui[now >> 1][1]] = now >> 1;
    		now = now >> 1;
    	}
    	return;
    }
    int main() {
    	n = IN();
    	memset(Dui, 0, sizeof(Dui));
    	Dui[0][0] = 0x3f3f3f3f;
    	for (register int i = 1; i <= n; i++) {
    		Add(IN());
    	}
    	m = IN();
    	for (register int i = 1; i <= m; i++) {
    		Do = IN();
    		switch (Do) {
    			case 0 : {
    				if(cnt == 0){
    					printf("%d
    ",-0x3f3f3f3f); 
    				}
    				else{ 
    					printf("%d
    ", Dui[1][0]);
    				}
    				break;
    			}
    			case 1 : {
    				Add(IN());
    				break;
    			}
    			case 2 : {
    				Del(IN());
    				break;
    			}
    		}
    	}
    	return 0;
    }
    
  • 相关阅读:
    方法的封装与调用(十)
    适配器设计模式及GenericServlet(九)
    错误页设置,设置HTTP状态码404,500(八)
    设置默认首页(七)
    ServletContext接口(六)
    javax.servlet.ServletConfig接口(五)
    C语言第2天基本运算
    再议extern和include的作用
    C语言中的++和--
    C语言培训第一天
  • 原文地址:https://www.cnblogs.com/Wild-Donkey/p/13329965.html
Copyright © 2011-2022 走看看