Pagini recente » Cod sursa (job #1545939) | Cod sursa (job #1470554) | Cod sursa (job #1186396) | Cod sursa (job #2502196) | Cod sursa (job #1050640)
//Min Heap
//Requires optimizations
//Get rid of swaps (too many)
#include <stdio.h>
#include <cstring> //memset
#include <algorithm> //swap
using namespace std;
#define heapLEN 200001
#define SIZE(v) v[0]
#define ROOT(x) (x>>1)
#define LEFT(x) (x<<1)
#define RIGHT(x) ((x<<1)+1)
//val - imaginary array
//val[i] = value of ith inserted element
int heap[heapLEN]; //min-heap structure
int at[heapLEN]; //at[i] = position y of ith inserted element in heap
//at[i] = y
//heap[y] = val[i]
//heap[at[i]] = val[i]
int at_1[heapLEN]; //at_1[i] = position of the yth element from heap in at
//at_1[y] = i
//at_1 is the inverse function of at
//at_1[at[i]] = at[at_1[i]] = i
void percolate(int pos)
{
while(pos>1&&heap[ROOT(pos)]>heap[pos])
{
//current update is made on pos
//pos <- ROOT(pos) (reads pos takes ROOT(pos) properties
swap(heap[ROOT(pos)],heap[pos]);
swap(at[at_1[ROOT(pos)]],at[at_1[pos]]); //swap v[i], v[j]
swap(at_1[ROOT(pos)],at_1[pos]); //swap i, j
pos=ROOT(pos);
}
}
void sift(int pos)
{
while(pos<=SIZE(heap))
{
int next;
//get next element is this exists
if(RIGHT(pos)<=SIZE(heap))
heap[LEFT(pos)]<heap[RIGHT(pos)] ? next=LEFT(pos) : next=RIGHT(pos);
else
if(LEFT(pos)<=SIZE(heap))
next=LEFT(pos);
else return;
//check if min-heap property is kept
if(heap[pos]>heap[next])
{
swap(heap[pos],heap[next]);
swap(at[at_1[pos]],at[at_1[next]]);
swap(at_1[pos],at_1[next]);
pos=next;
}
else return;
}
}
void insert(int val)
{
//SIZE(heap) = SIZE(at_1)
//thinking of at, at_1 as functions then
//at: A -> B
//at_1: B -> A
//card(A) = card(B) (must)
//in code: SIZE(heap) != SIZE(at) (not always)
//in reality: SIZE(heap) == SIZE(at) (always)
++SIZE(heap);
heap[SIZE(heap)]=val;
++SIZE(at);
at[SIZE(at)]=SIZE(heap);
at_1[SIZE(heap)]=SIZE(at);
percolate(at[SIZE(at)]);
}
void cut(int pos)
{
//pos = at[i]
//SIZE(heap) = at[x]
//apply inverse function on the previous equations
//i = at_1[pos]
//x = at_1[SIZE(heap)]
swap(heap[pos],heap[SIZE(heap)]);
swap(at[at_1[pos]],at[at_1[SIZE(heap)]]);
swap(at_1[pos],at_1[SIZE(heap)]);
//after the swap the last element in the heap is not needed anymore
//0 in at array means that element is not in use
//SIZE(at) - COUNT(0s in at) = SIZE(heap)
heap[SIZE(heap)]=0;
at[at_1[SIZE(heap)]]=0;
at_1[SIZE(heap)]=0;
--SIZE(heap);
if(pos<=SIZE(heap)) //check corectness of pos
//case when the cut is made on the last element of the heap
if(pos>1&&heap[ROOT(pos)]>heap[pos]) percolate(pos);
else sift(pos);
}
int main()
{
freopen("heapuri.in","r",stdin);
freopen("heapuri.out","w",stdout);
memset(heap,0,sizeof(heap));
memset(at,0,sizeof(at));
memset(at_1,0,sizeof(at_1));
int N;
scanf("%d",&N);
while(N--)
{
int cod;
scanf("%d",&cod);
switch(cod)
{
case 1:
int val;
scanf("%d",&val);
insert(val);
break;
case 2:
int i;
scanf("%d",&i);
cut(at[i]);
break;
case 3:
printf("%d\n",heap[1]);
break;
}
/***DEBUG***
if(cod!=3)
{
printf("SIZE(heap) = %d\n",SIZE(heap));
printf("SIZE(at) = %d\n",SIZE(at));
printf("heap : ");
for(int i=1;i<=SIZE(heap);++i)
printf("%d ",heap[i]);
printf("\nat : ");
for(int i=1;i<=SIZE(at);++i)
printf("%d ",at[i]);
printf("\nat_1 : ");
for(int i=1;i<=SIZE(heap);++i)
printf("%d ",at_1[i]);
printf("\n\n");
}
*/
}
return 0;
}