知识储备
树状数组:顾名思义,树状数组类似于线段树,但是功能可能没有那么完善,但是还是有它的用武之地的。
其中一个很重要的处理就是lowbit,即我们选择该数中二进制从右往左的第一个1。x&(-x)中,我们可以知道负数是以补码的形式来实现的,也就是整数的反码+1,然后进行与操作。这个我们可以得到第一个为1的位置。
详细操作、
1057-stack
贴一下柳神代码,个人代码太烂了。
#include <cstdio>
#include <stack>
#define lowbit(i) ((i) & (-i))
const int maxn = 100010;
using namespace std;
int c[maxn];
stack<int> s;
void update(int x, int v) {
for(int i = x; i < maxn; i += lowbit(i))
c[i] += v;
}
int getsum(int x) {
int sum = 0;
for(int i = x; i >= 1; i -= lowbit(i))
sum += c[i];
return sum;
}
void PeekMedian() {
int left = 1, right = maxn, mid, k = (s.size() + 1) / 2;
while(left < right) {
mid = (left + right) / 2;
if(getsum(mid) >= k)
right = mid;
else
left = mid + 1;
}
printf("%d\n", left);
}
int main() {
int n, temp;
scanf("%d", &n);
char str[15];
for(int i = 0; i < n; i++) {
scanf("%s", str);
if(str[1] == 'u') {
scanf("%d", &temp);
s.push(temp);
update(temp, 1);
} else if(str[1] == 'o') {
if(!s.empty()) {
update(s.top(), -1);
printf("%d\n", s.top());
s.pop();
} else {
printf("Invalid\n");
}
} else {
if(!s.empty())
PeekMedian();
else
printf("Invalid\n");
}
}
return 0;
}
注:树状数组可以作为一种排序的参考方式,个人感觉类似于桶排序。那记录下该模板和思想。