L3-002 特殊堆栈 (30 分)

传送门
用vector模拟堆栈,这里主要是一个中位数比较难搞,但是实际上这题的数据不太大,可以直接暴力用vector插入(这里我查了下vector的insert的复杂度好像是O(n)的,stl会快一点,但是实际还是O(n),如果来组1e5的倒序Push感觉是会炸的,最差是1e9

insert(it,x) it是迭代器,配合lower_bound构造的数列是非严格递增的
code:

#include <bits/stdc++.h>
using namespace std;

vector<int> v1, v;
vector<int>::iterator it;

int main() {
    ios::sync_with_stdio(0); cin.tie(0); cout.tie(0);
	int n;
	cin >> n;
	string op;
	int x;
	while(n--) {
		cin >> op;
		if(op == "Push") {
			cin >> x;
			v1.push_back(x);
			it = lower_bound(v.begin(), v.end(), x);
			v.insert(it, x);
		}
		else if(op == "Pop") {
			if(v1.size() == 0) {
				cout <<"Invalid\n";
				continue;
			}
			it = lower_bound(v.begin(), v.end(), v1[v1.size() - 1]);
			v.erase(it);
			cout << v1[v1.size() - 1] << endl;
			v1.pop_back();
		}
		else {
			if(v1.size() == 0) {
				cout <<"Invalid\n";
				continue;
			}
			if(v1.size() & 1) cout << v[v.size() / 2] << endl;
			else cout << v[v.size() / 2 - 1] << endl;
		} 
	}
	
	return 0;
}

正解大概还是树状数组之类的,二分mid作为中位数,树状数组获取1-x的和的复杂度是logn的,删除也是logn,二分也是logn,nlognlogn。最差是1e7 实际达不到

code:

#include <bits/stdc++.h>
using namespace std;

const int N = 1e5 + 10;

int tr[N];
stack<int> s;

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

void update(int p, int x) {
	for(int i = p; i < N; i += lowbit(i)) {
		tr[i] += x;
	}
}

int getSum(int x) {
	int res = 0;
	for(int i = x; i > 0; i -= lowbit(i)) {
		res += tr[i];
	}
	return res;
}

int searchAns() {
	int l = 1, r = N - 1, k = (s.size() + 1) / 2;
	int ans = l;
	while(l <= r) {
		int mid = (l + r) >> 1;
		if(getSum(mid) >= k) {
			ans = mid;
			r = mid - 1;
		}
		else {
			l = mid + 1;
		}
	}
	return ans;
} 

int main() {
	int n;
	cin >> n;
	string op;
	int x;
	while(n--) {
		cin >> op;
		if(op == "Push") {
			cin >> x;
			s.push(x);
			update(x, 1);
		}
		else if(op == "Pop") {
			if(s.size() == 0) {
				cout <<"Invalid\n";
				continue;
			}
			cout << s.top() << endl;
			update(s.top(), -1);
			s.pop();
		}
		else {
			if(s.size() == 0) {
				cout <<"Invalid\n";
				continue;
			}
			cout << searchAns() << endl;
		} 
	}
	
	return 0;
} 

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值