您的位置:首页 > 其它

L3-2 堆栈 团体程序设计天梯赛-练习集

2016-05-14 19:08 323 查看
    这题其他的好做,关键是查询中间值,用个树状数组维护值的数量,然后用二分查找在中间的值就好。

#include <iostream>
#include <algorithm>
#include <stdio.h>
#include <string.h>
#include <vector>
#include <math.h>
#include <time.h>
#include <map>
#define mem(a, b) memset(a, b, sizeof(a))
#define inf (1e8 + 7)
using namespace std;

int st[100005], head = 0, num[100005], num2[100005];
bool vis[100005];
char ch[25];

void add(int a)
{
for(int i = a;i <= 100000;i += (i&(-i)))
num[i]++;
}

void sub(int a)
{
for(int i = a;i <= 100000;i += (i&(-i)))
num[i]--;
}

int get(int a)
{
int sum = 0;
for(int i = a;i > 0;i -= (i&(-i)))
sum += num[i];
return sum;
}

int solve(int a)
{
int lo = 1, hi = 100000;
while(lo <= hi)
{
int mid = (lo + hi) / 2;
int tmp1 = get(mid - 1);
int tmp2 = get(mid);
if(tmp1 < a&&tmp2 >= a)
{
if(num2[mid])
return mid;
for(int i = mid - 1;i >= 1;i--)
if(num2[i])
return i;
}
else if(tmp1 >= a)
hi = mid - 1;
else
lo = mid + 1;
}
}

void push(int a)
{
st[++head] = a;
num2[a]++;
add(a);
}

void pop()
{
if(!head)
printf("Invalid\n");
else
{
int tmp = st[head--];
num2[tmp]--;
sub(tmp);
printf("%d\n", tmp);
}
}

void getmid()
{
if(!head)
printf("Invalid\n");
else
{
int pos;
if(head % 2)
pos = (head + 1) / 2;
else
pos = head / 2;
printf("%d\n", solve(pos));
}
}

int main ()
{
mem(num, 0);
mem(num2, 0);
int n, a;
scanf("%d", &n);
for(int i = 1;i <= n;i++)
{
scanf("%s", ch);
if(!strcmp(ch, "Pop"))
pop();
else if(!strcmp(ch, "PeekMedian"))
getmid();
else if(!strcmp(ch, "Push"))
{
scanf("%d", &a);
push(a);
}
else
printf("Invalid\n");
}
return 0;
}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签:  L3-2 堆栈