随时查找中位数——pat1057

http://pat.zju.edu.cn/contests/pat-a-practise/1057

题目的意思是可以在一个可以任意添加于删除整数的集合里随时查找该集合的中位数

每次查找用nlogn的方法显然会超时

所以要一种方法接近0(N)的查找方法,  ( 计算第k大的数会超时!!)

比如当前有1,4,7 

则树状数组的sum结果会是 1,1,1,2,2,2,3

现在就变成了二分查找(3+1)/2 ,即2的最左端的位置

 

ps: 2分查找有两种形式 (有一种会出错)

int find(int value)// 1,2,3 

{

    int mid,ll=1,rr=3;

    while(ll<=rr)

    {    

        mid=(ll+rr)/2;

        if(value<=s[mid])rr=mid-1;

        else ll=mid+1; 

    }

    return ll;

}

这种查找1,2,3都不会出错

 

int find(int value)//1,2,3

{

    int mid,ll=1,rr=3;

    while(ll<rr-1)

    {    

        mid=(ll+rr)/2;

        if(value<=s[mid])rr=mid;

        else ll=mid; 

    }

    return rr;

}

这种查找1是会出错!!!

 

随时查找中位数——pat1057
#include<stdio.h>

#include<string.h>

#include<iostream>

#include<stack>

using namespace std;



int n=100000;

int tree[110009];

int add[110009];

int size=0;



int lowbit(int x)

{

    return x&(-x);

}



void updata(int x,int c)

{

    int i;

    for(i=x;i<=n;i+=lowbit(i))

    {

        tree[i]+=c;

    }

}



int getsum(int x)

{

    int i;

    int temp=0;

    for(i=x;i>=1;i-=lowbit(i))

    {

        temp+=tree[i];

    }

    return temp;

}



int find()

{

    int ll=0,rr=100000,mid=(ll+rr)/2;



    int sum;

    while(ll<=rr){

        mid=(ll+rr)/2;

        sum=getsum(mid);

        if(sum< ((size+1)/2)) ll=mid+1;

        else if(sum> ((size+1)/2)) rr=mid-1;

        else if(sum == ((size+1)/2)) rr=mid-1;

    }

    return ll;

}



int main()

{

    int t;

    scanf("%d",&t);

    int i,temp;

    char ss[99];

    stack<int>sta;

    for(i=0;i<=n;i++){

        tree[i]=0;

        add[i]=0;

    }

    

    for(i=1;i<=t;i++){

        scanf("%s",ss);

        if(ss[2]=='p'){

            if(size==0){

                printf("Invalid\n");

            }else{

                printf("%d\n",sta.top());

                updata(sta.top(),-1);

                add[sta.top()]--;

                sta.pop();

                size--;

            }

        }

        

        if(ss[2]=='s'){

            scanf("%d",&temp);

            add[temp]++;

            sta.push(temp);

            updata(temp,1);

            size++;

        }

        

        if(ss[2]=='e'){

            if(size==0){

                printf("Invalid\n");

            }else{

                printf("%d\n",find());

            }

        }

    }

    

    return 0;

}
View Code

 

你可能感兴趣的:(pat)