1. 程式人生 > >CCCC-GPLT L2-012. 關於堆的判斷 堆

CCCC-GPLT L2-012. 關於堆的判斷 堆

按順序向一個小頂堆中插入N(1000)個數據(-1e4,1e4),然後給出M(20)個查詢,查詢包括
查詢x是否為堆頂
查詢x和y是否為兄弟節點
查詢x是否是y的父節點
查詢x是否是y的一個子節點

直接用std::priority_queue是無法實現這四個查詢的,正好複習一下堆.
堆是一種用陣列實現的完全二叉樹,有關二叉堆一共包括4個操作:
1.建堆
2.插入
3.獲得根節點值
4.刪除根節點
二叉堆分為最小堆和最大堆.
自己實現了一波,過了luogu3378.
注意一切與陣列有關的操作,實現時考慮以1開始還是以0開始,開區間還是閉區間.

本題一個值可能有多重位置,好在資料規模極小,直接遍歷搜尋即可.
首先建堆,注意不能makeheap而得一個一個插入,
難受的讀入環節之後,判斷值就好了.
判斷根可以==1,判斷父子<<1,判斷兄弟^1.(我的根節點是1,為0的會有所不同)

/* LittleFall : Hello! */
#include <bits/stdc++.h>
#define ll long long
using namespace std;
inline int read();
inline void write(int x);
const int M = 100016;
//heap.cpp 堆,最下方4個函式為public
int heap[M], heap_size; //from 1,small root
// change 4 to big root
// siftdown 2
// pushup 1
// delroot INT_MAX
inline int
left(int p) { return p << 1; } inline int right(int p) { return p << 1 | 1; } void siftdown(int p) { int tmp = heap[left(p)] < heap[right(p)] ? left(p) : right(p); if(heap[p] <= heap[tmp]) return; swap(heap[p], heap[tmp]); siftdown(tmp); } void pushup(int
p) { if(p == 1) return; int fa = p >> 1; if(heap[p] >= heap[fa]) return; swap(heap[p], heap[fa]); pushup(fa); } //public void makeheap(int size) { for(int i = size >> 1; i >= 1; i++) siftdown(i); } void insert(int num) { heap[++heap_size] = num; pushup(heap_size); } int delroot() { int res = heap[1]; heap[1] = heap[heap_size]; heap[heap_size--] = INT_MAX; siftdown(1); return res; } int getroot() { return heap[1]; } int main(void) { #ifdef _LITTLEFALL_ freopen("in.txt","r",stdin); #endif //std::cin.sync_with_stdio(false); int n=read(),m=read(); for(int i=0;i<n;i++) insert(read()); for(int i=0;i<m;i++) { int a,b,ans=0,id; scanf("%d",&a); char tmp[20]; scanf("%s",tmp); if(tmp[0]=='i') { scanf("%s",tmp); if(tmp[0]=='t') { scanf("%s",tmp); if(tmp[0]=='r') { //%d is the root ans=(heap[1]==a); } else { scanf("%s",tmp); scanf("%d",&b); //%d is the parent of %d for(id=2;id<=heap_size;id++) if(heap[id]==b&&heap[id>>1]==a) ans=1; } } else { scanf("%s",tmp); scanf("%s",tmp); scanf("%d",&b); //%d is a child of %d for(id=2;id<=heap_size;id++) if(heap[id]==a&&heap[id>>1]==b) ans=1; } } else { scanf("%d",&b); cin.getline(tmp,200); //%d and %d are siblings for(id=2;id<=heap_size;id++) if(heap[id]==a&&heap[id^1]==b) ans=1; } printf("%c\n",ans?'T':'F' ); } return 0; } inline int read() { int x=0,f=1;char ch=getchar(); while(ch<'0'||ch>'9') {if(ch=='-')f=-1;ch=getchar();} while(ch>='0'&&ch<='9'){x=x*10+ch-'0';ch=getchar();} return x*f; } inline void write(int x) { if(x<0) putchar('-'),x=-x; if(x>9) write(x/10); putchar(x%10+'0'); }