Pat1057 树状数组求中位数,这题还有结合二分查找,不然后超时

#include<iostream>  
#include<cstdio>  
#include<stack>  
#include<cstring>  
using namespace std;  
#define lowbit(x) x&(-x)  
#define N 100010  
int c[N];  
void add(int i,int val)  
{  
    while(i<N)  
    {  
        c[i]+=val;  
        i+=lowbit(i);  
    }  
}  
int getsum(int i)  
{  
    int sum=0;  
    while(i>0)  
    {  
        sum+=c[i];  
        i-=lowbit(i);  
    }  
    return sum;  
}  
int binsearch()  
{  
    int l=1,r=100000;  
    int k=getsum(100000);  
    k=(k+1)/2;  
    while(l<r)  
    {  
        int mid=(l+r)>>1;  
        if(getsum(mid)>=k)r=mid;  
        else l=mid+1;  
    }  
    return r;  
}  
  
int main()  
{  
    char op[20];  
    int n;  
    stack<int>q;  
    while(~scanf("%d",&n))  
    {  
        memset(c,0,sizeof(c));  
        while(!q.empty())q.pop();  
        while(n--)  
        {  
            scanf("%s",op);  
            if(strcmp(op,"Pop")==0)  
            {  
                if(q.empty())  
                {  
                    printf("Invalid\n");  
                }  
                else {  
                    printf("%d\n",q.top());  
                    add(q.top(),-1);  
                    q.pop();  
                }  
            }  
            else if(strcmp(op,"PeekMedian")==0)  
            {  
                if(q.empty()){  
                    printf("Invalid\n");  
                }  
                else  
                {  
                    printf("%d\n",binsearch());  
                }  
            }  
            else  
            {  
                int x;  
                scanf("%d",&x);  
                q.push(x);  
                add(x,1);  
            }  
            //for(int i=0;i<10;i++)printf("  ** %d %d\n",i,getsum(i));  
        }  
    }  
  
    return 0;  
}  
PAT1057

 

zcmu1203数转数组求逆序数,数据需要离散化,离散化时注意不要把0放进去,否则会死循环

#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
const int M=50004;
int a[M],b[M],c[M];
int Lowbit(int x){
    return x&-x;
}
void Update(int x,int y){
    int i;
    for(i=x;i<M;i+=Lowbit(i)){
        c[i]+=y;
    }
}
int Sum(int x){
    int i,ans=0;
    for(i=x;i;i-=Lowbit(i)){
        ans+=c[i];
    }
    return  ans;
}
int main(){
    int n,i,k,m,ans;
    while(~scanf("%d",&n)){
        memset(c,0,sizeof(c));
        for(i=1;i<=n;i++){
            scanf("%d",a+i);
            b[i]=a[i];
        }
        sort(b+1,b+1+n); //第一步:排序
        m=unique(b+1,b+1+n)-(b+1); //第二部:去重
        ans=0;
        for(i=1;i<=n;i++){
            k=lower_bound(b+1,b+1+m,a[i])-(b); //第三步 离散
            Update(k,1);
            ans+=(i-1-Sum(k-1));
        }
        printf("%d\n",ans);
    }
    return 0;
}
zcmu1203

 

hdu5124 n个线段,问被覆盖最多次的点有几条线段,数据需要离散化

树状数组基础题
离散时注意不要把0 放进去
#include<cstdio>
#include<algorithm>
#include<cstring>
using namespace std;
#define maxn 100010
#define low(x) x&(-x)
int n,m;
int arr[maxn*2];
struct ss
{
    int l,r;
}p[maxn];
int sh[maxn*2];//hash
int c[maxn];
void add(int i,int val)
{
    while(i<n+m+1)
    {
        c[i]+=val;
        i+=low(i);//i=0会死循环
    }
}
int getsum(int i)
{
    int ans=0;
    while(i>0)
    {
        ans+=c[i];
        i-=low(i);
    }
    return ans;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(c,0,sizeof(c));
        scanf("%d",&n);
        for(int i=0;i<n;i++)
        {
            scanf("%d%d",&p[i].l,&p[i].r);
            arr[i*2]=p[i].l;
            arr[i*2+1]=p[i].r;
        }

        sort(arr,arr+2*n);//第一步:排序
        m=unique(arr,arr+2*n)-arr;//第二部:去重
        for(int i=0;i<n;i++)
        {
            int x=lower_bound(arr,arr+m,p[i].l)-arr+1;//第三步 离散
            int y=lower_bound(arr,arr+m,p[i].r)-arr+1;
            add(x,1);
            add(y+1,-1);
        }
        int maxNum=0;
        for(int i=0;i<n+m+1;i++)
        {
            int tmp=getsum(i);
            if(maxNum<tmp)maxNum=tmp;
        }
        printf("%d\n",maxNum);

    }
}
HDU5124

 

posted on 2014-12-01 08:46  kylehz  阅读(446)  评论(0编辑  收藏  举报