CCCC-GPLT L2-012. 關於堆的判斷 堆
阿新 • • 發佈:2019-01-22
按順序向一個小頂堆中插入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');
}