用sort只过得15分
大佬们都用了树状数组
没用树状数组的思路看懂了但是那个语法不会写
树状数组
个人理解:用lowbit把a化成二进制,查零,有k个零的时候,a+k为父亲数组,a-k为上一个是父亲数组的数组
不过题解的代码里没看明白这个是怎么用的。。。迷茫
更新:
树状数组的用法
首先理解好存储方式的图
lowbit函数理解:返回数转化为二进制后从末尾开始第一个1
比如: 3 二进制是 0011 lowbit(3)返回 0001
10 二进制是1010 lowbit(10)返回 0010
定义:#define lowbit(i) ((i)&(-i))
求区间和:
int Sum(int x){//前x项的和
int ANS=0;
while(x>0){
ANS+=C[x];
x-=lowbit(x);
}
return ANS;
}
因为数据之间是有关联性的
所以要有更新函数:
void update (int i,int x){ //i点增加x
while (i <= N){ //N为原数组长度
tree[i] += x;
i += Lowbit(i);
}
}
本题中是把数出现的次数存到数组里,不是求数的和↓
用string会超时
#include <cstdio>
#include <iostream>
#include <stack>
#define lowbit(i) ((i)&(-i))
using namespace std;
stack<int> arr;
const int maxn = 100010;
int use[maxn];
int n, sum;
string a = "Push", b = "Pop", c = "PeekMedian"; //用string会超时
void update(int x, int v){
for(int i = x; i<maxn; i += lowbit(i))
use[i] += v;
}
int su(int x){
int fin = 0;
for(int i=x; i>=1; i -= lowbit(i))
fin += use[i];
return fin;
}
void pek(){
int left = 1, right = maxn, mid, k = (arr.size()+1)/2;
while(left < right){
mid = (left+right)/2;
if(su(mid) >= k) right = mid;
else left = mid + 1;
}
printf("%d\n",left);
}
int main(){
scanf("%d",&n);
for(int i=0; i<n; i++){
int in;
char stu[15];
scanf("%s",&stu);
if( stu[1]=='u') {
scanf("%d",&in);
arr.push(in);
update(in,1);
sum++;
}
else if(stu[1] == 'o') {
if(sum != 0) {
printf("%d\n",arr.top());
update(arr.top(),-1);
sum--;
arr.pop();
}
else printf("Invalid\n");
}
else if(stu[1] == 'e') {
if(sum != 0)
pek();
else printf("Invalid\n");
}
}
return 0;
}
超时代码↓
#include <cstdio>
#include <iostream>
#include <stack>
#include <algorithm>
using namespace std;
stack<int> arr;
int use[11000];
int n, sum;
string a = "Push", b = "Pop", c = "PeekMedian";
int main(){
scanf("%d",&n);
for(int i=0; i<n; i++){
string v;
int in;
cin >> v;
if( v == a) {
scanf("%d",&in);
arr.push(in);
use[sum] = in;
sum++;
//use[sum] = use[sum-1] + in;
}
else if(v == b) {
if(sum != 0) {
printf("%d\n",arr.top());
use[sum] = 0;
sum--;
arr.pop();
}
else printf("Invalid\n");
}
else if(v == c) {
if(sum != 0){
//int fin = use[(sum+1)/2 ] - use[(sum+1)/2 - 1];
//sort(use,use+sum);
//for(int k=0; k<sum; k++) cout << use[k] << " " << k << endl;
int fin = use[(sum+1)/2-1];
printf("%d\n",fin);
}
else printf("Invalid\n");
}
}
return 0;
}