程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> C語言 >> C++ >> C++入門知識 >> Hdu 4006 The kth great number (數據結構_SBT)

Hdu 4006 The kth great number (數據結構_SBT)

編輯:C++入門知識

題目大意: 給定n個操作,操作分兩種,插入和查詢第k大的數。n<=1000000

解題思路:因為本題沒有刪除操作,所以變得特別簡單,只需要維護一個大小為k的小頂堆即可。
   但是如果有刪除操作,就變地復雜了,所以用SBT寫了這道題,怒寫2遍,明天晚上黃金十點半再寫三遍,測模版的沒什麼好說的。

測試數據:
8 3
I 1
I 2
I 3
Q
I 5
Q
I 4
Q

C艹代碼:
[cpp] 
#include <stdio.h> 
#include <string.h> 
#define MAX 1000010 
 
 
int n,m; 
struct SBT { 
 
    int left,right,size,key; 
    void Init() { 
 
        left = right = 0; 
        size = 1; 
    } 
}a[MAX]; 
int tot,root; 
 
 
void left_rotate(int &t) { 
 
    int k = a[t].right; 
    a[t].right = a[k].left; 
    a[k].left = t; 
    a[k].size = a[t].size; 
    a[t].size = a[a[t].left].size + a[a[t].right].size + 1; 
    t = k; 

void right_rotate(int &t) { 
 
    int k = a[t].left; 
    a[t].left = a[k].right; 
    a[k].right = t; 
    a[k].size = a[t].size; 
    a[t].size = a[a[t].left].size + a[a[t].right].size + 1; 
    t = k; 

void maintain(int &t,int flag) { 
 
    if (flag == 0) { 
 
        if (a[a[a[t].left].left].size > a[a[t].right].size)  
            right_rotate(t); 
        else if (a[a[a[t].left].right].size > a[a[t].right].size) 
            left_rotate(a[t].left),right_rotate(t); 
        else return; 
    } 
    else { 
 
        if (a[a[a[t].right].right].size > a[a[t].left].size) 
            left_rotate(t); 
        else if (a[a[a[t].right].left].size > a[a[t].left].size) 
            right_rotate(a[t].right),left_rotate(t); 
        else return; 
    } 
    maintain(a[t].left,0); 
    maintain(a[t].right,1); 
    maintain(t,0); 
    maintain(t,1); 

void insert(int &t,int v) { 
 
    if (t == 0) 
        t = ++tot,a[t].Init(),a[t].key = v; 
    else { 
 
        a[t].size++; 
        if (v < a[t].key) 
            insert(a[t].left,v); 
        else insert(a[t].right,v); 
        maintain(t,v>=a[t].key); 
    } 

int del(int &t,int v) { 
 
    if (!t) return 0; 
    a[t].size--; 
 
    if (v == a[t].key || v < a[t].key && !a[t].left 
        || v > a[t].key && !a[t].right) { 
 
        if (a[t].left && a[t].right) { 
 
            int p = del(a[t].left,v+1); 
            a[t].key = a[p].key; 
            return p; 
        } 
        else { 
 
            int p = t; 
            t = a[t].left + a[t].right; 
            return p; 
        } 
    } 
    else return del(v<a[t].key?a[t].left:a[t].right,v); 

int find(int t,int k) { 
 
    if (k <= a[a[t].left].size) 
        return find(a[t].left,k); 
    if (k > a[a[t].left].size + 1) 
        return find(a[t].right,k-a[a[t].left].size-1); 
    return a[t].key; 

 
 
int main() 

    int i,j,k; 
 
 
    while (scanf("%d%d",&n,&m) != EOF) { 
 
        tot = root = 0; 
        char ope[10]; 
        while (n--) { 
 
            scanf("%s",ope); 
            if (ope[0] == 'I') { 
 
                scanf("%d",&k); 
                insert(root,k); 
            } 
            else printf("%d\n",find(root,a[root].size+1-m)); 
        } 
    } 

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved