1057. Stack (30)-中位数-BIT
Stack is one of the most fundamental data structures, which is based on the principle of Last In First Out (LIFO). The basic operations include Push (inserting an element onto the top position) and Pop (deleting the top element). Now you are supposed to implement a stack with an extra operation: PeekMedian -- return the median value of all the elements in the stack. With N elements, the median value is defined to be the (N/2)-th smallest element if N is even, or ((N+1)/2)-th if N is odd.
Input Specification:
Each input file contains one test case. For each case, the first line contains a positive integer N (<= 105). Then N lines follow, each contains a command in one of the following 3 formats:
Push keyPop
PeekMedian
where key is a positive integer no more than 105.
Output Specification:
For each Push command, insert key into the stack and output nothing. For each Pop or PeekMedian command, print in a line the corresponding returned value. If the command is invalid, print "Invalid" instead.
Sample Input:17 Pop PeekMedian Push 3 PeekMedian Push 2 PeekMedian Push 1 PeekMedian Pop Pop Push 5 Push 4 PeekMedian Pop Pop Pop PopSample Output:
Invalid Invalid 3 2 2 1 2 4 4 5 3 Invalid
推荐指数※※
来源:http://pat.zju.edu.cn/contests/pat-a-practise/1057
这道题如果不考虑时间限制,那是比较简单的,一开始就直接使用一个数组计数,使用二分法搜索,但都是超时。
这样只能用上统计累计频次比较好的Bianry Indexed Tree(http://community.topcoder.com/tc?module=Static&d1=tutorials&d2=binaryIndexedTrees).
还有这里cin,cout还是不要用了,效率不如printf和scanf。
#include<iostream> #include<string.h> #include<stdio.h> using namespace std; #define Maxval 100009 int tree[Maxval+1]; int stack[Maxval+1]; void update(int idx,int val){ while(idx<Maxval){ tree[idx]+=val; idx+=(idx&-idx); } } int read(int idx){ int sum=0; while(idx>0){ sum+=tree[idx]; idx-=(idx&-idx); } return sum; } int find_cumulate(int cumfre){ int low=0,high=Maxval,mid; while(low<high-1){ if((low+high)&1==1) mid=(low+high-1)/2; else mid=(low+high)/2; int sum=read(mid); if(sum>=cumfre) high=mid; else low=mid; } return high; } int main(){ int n,i; char str[20]; scanf("%d",&n); long tmp,top; memset(tree,0,Maxval*sizeof(int)); memset(stack,0,Maxval*sizeof(int)); top=0; for(i=0;i<n;i++){ scanf("%str",str); if(str[1]=='o'){//POP if(top>0){ tmp=stack[top--]; printf("%d\n",tmp); update(tmp,-1); } else printf("Invalid\n"); } else if(str[1]=='u'){//push cin>>tmp; stack[++top]=tmp; update(tmp,1); } else if(str[1]=='e'){//media if(top>0){ if(top&1==1) tmp=(top+1)/2; else tmp=top/2; tmp=find_cumulate(tmp); printf("%d\n",tmp); } else printf("Invalid\n"); } else{ printf("Invalid\n"); } } return 0; }
这是我超时的代码,比较的朴素
#include<iostream> #include<string.h> #include<string> #include<stack> #include<vector> #include<set> #include<algorithm> #define N 100000 #define Hash_N 10000 using namespace std; long find_median(long *arr,long first,long last,long val){ long mid; while(first<last&&first!=0&&last!=Hash_N-1){ mid=(first+last)/2; if(arr[mid]==val){ return mid; }else if(arr[mid]>val) last=mid; else first=mid; } return first; } int main() { long n,i,j; char str[20]; long totalnum,num[N],hash_num[Hash_N]; stack<long> st; cin>>n; totalnum=0; long tmp; memset(num,0,N*sizeof(int)); memset(hash_num,0,Hash_N*sizeof(int)); long fhash=N/Hash_N; for(i=0;i<n;i++){ cin>>str; if(strcmp(str,"Pop")==0){//POP if(!st.empty()){ tmp=st.top(); cout<<tmp<<endl; st.pop(); totalnum--; num[tmp]--; for(j=tmp/fhash;j<Hash_N;j++) hash_num[j]--; } else cout<<"Invalid"<<endl; } else if(strcmp(str,"Push")==0){//push cin>>tmp; st.push(tmp); totalnum++; num[tmp]++; hash_num[tmp/fhash]++; } else{//media if(!st.empty()){ if(totalnum&1==1) tmp=(totalnum+1)/2; else tmp=totalnum/2; long tmp_sum=0,k; k=find_median(hash_num,0,Hash_N,tmp); if(k>0) tmp_sum=hash_num[k-1]; else tmp_sum=0; for(j=k*fhash;j<N;j++){ tmp_sum+=num[j]; if(tmp_sum>=tmp){ cout<<j<<endl; break; } } } else cout<<"Invalid"<<endl; } } return 0; }

本文探讨了在给定数据集上实现堆排序并优化中位数计算的方法,利用二叉索引树(Binary Indexed Tree)进行高效查找与更新操作,避免了传统排序方法在大规模数据集上的性能瓶颈。
4470

被折叠的 条评论
为什么被折叠?



