cjweffort

博客园 首页 联系 订阅 管理

题目限定数的范围N<=100000

关键点:构建树状数组可以求解前n个数的和

由此push和pop时要维护树状数组,当需要求解median时,使用二分法

由此总的算法复杂度为O(N*logN+N*logn*logN)=O(N*logN*logN)

// 1057. Stack (30).cpp : 定义控制台应用程序的入口点。
//

#include "stdafx.h"
#include <stdio.h>
#include <string.h>

const int N = 100003;
int ind[N];
int data[N];
int vol[N];
int ssize;

int lowbit(int x){
	return x & (-x);
}

void update(int pos, int inc){
	while(pos <= N){
		ind[pos] += inc;
		pos += lowbit(pos);
	}
}

int sum(int pos){
	int ret = 0;
	while(pos > 0){
		ret += ind[pos];
		pos -= lowbit(pos);
	}
	return ret;
}

//binarySearch the minimum value x that sum(x) = keyValue(the ascend sorting index of median)
int binarySearch(int low, int high, int keyValue){
	while(low <= high){
		int mid = (low + high) / 2;
		int tmpSum = sum(mid);
		if(keyValue <= tmpSum)
			high = mid - 1;
		else
			low = mid + 1;
	}
	return low;
}

int main(){
	int cas;
	scanf("%d", &cas);
	memset(ind, 0, sizeof(ind));
	memset(vol, 0, sizeof(vol));
	char cmd[13];
	ssize = 0;
	while(cas--){
		scanf("%s", cmd);
		if(cmd[1] == 'u'){
			int tmp;
			scanf("%d", &tmp);
			data[ssize] = tmp;
			vol[tmp]++;
			update(tmp, 1);
			ssize++;
		}
		else if(cmd[1] == 'o'){
			if(ssize == 0)
				printf("Invalid\n");
			else{
				update(data[--ssize], -1);
				printf("%d\n", data[ssize]);
			}
		}
		else{
			if(ssize == 0)
				printf("Invalid\n");
			else{
				int keyValue = (ssize & 0x01) ? (ssize + 1) / 2 : (ssize / 2);
				int ans = binarySearch(1, N, keyValue);
				printf("%d\n", ans);
			}	
		}
	}
	return 0;
}



posted on 2013-10-14 23:41  cjweffort  阅读(169)  评论(0编辑  收藏  举报