zoukankan      html  css  js  c++  java
  • Above the Median

    http://www.forioi.com/p/3212

    农夫约翰把他的N(1<=N<=1e5)奶牛排在一排来衡量他们的高度,牛i有:高度H_I(1<=H_I<=1e9)纳米–因为FJ认为他需要精确测量!他想选择一些连续的奶牛拍一张照片发给牛摄影大赛。大赛有一个很奇怪的规则,对所有提交的照片:照片有效当且仅当,它描绘了一群中位身高至少大于一定的阈值X(1<=x<=1e9)的奶牛。中位身高定义为:有n头奶牛按从小到大顺序排好,第[(1+n)/2](取上限)头奶牛的身高。例如{7,3,2,6}的中位数是6,和{5,4,8}的中位数是5。FJ想知道他有多少种选择。

    输入
    *第1行:两个用空格隔开的整数:N和X
    *第2 .. N 1:第i行1包含单个整数H_I。

    输出
    *第1行:选择的个数,注意,该数可能超出32位整数的存储范围。

    样例
    输入
    复制
    4 6
    10
    5
    6
    2
    输出
    复制
    7
    提示
    有10个可能选择。其中,只有7 个的中位数大于6。它们是{10},{6},{10,5},{5,6},{6,2},{10, 5,6},{1
    0,5,6,2}

    首先我们分析一下这一个题
    假如有n个数,那么只需要有n/2个数比X大就可以满足条件
    我们把设置一个num[i]来表示前i个数大于等于x的有几个,
    只要这个数大于等于x,num[i]=num[i-1]+1,else num[i]=num[i-1]-1
    我们可以发现,只要num[i]>=0那么就可以满足条件,ans++
    比如前五个数是:3 2 4 6 1 x是3
    那么前1个数的num[1]=num[0]+1(3>=3)
    那么前2个数的num[2]=num[1]-1(2<3)
    那么前3个数的num[3]=num[2]+1(4>=3)
    那么前4个数的num[4]=num[3]+1(6>=3)
    那么前5个数的num[5]=num[4]-1(1<3)
    那如果是求第2个到第5个是否满足条件呢
    那我么就可以把前5个数的num减去前1个数的num(2也在这个区间,所以不需要减去)
    也就是num[5]-num[2-1] =1-1=0
    所以求第i到j个的和就可以直接得出=num[j]-num[i-1]
    求num

    for(int i=1;i<=n;i++)
    {
    cin>>a[i];
    if(a[i]>=x) num[i]=num[i-1]+1;
    else num[i]=num[i-1]-1;
    }


    所以我们只需要做一遍查找,看枚举num[j]-num[i]是否大于0

    for(int j=1;j<=n;j++)
    for(int i=1;i<=j;i++)
    if(num[j]-num[i]>=0) 
    ans++;


    但这样太慢了。。。
    我们来想一下优化:
    其实查找就是找前i个有多少个小于num[i],我们可以来用树状数组来优化

    不会写树状数组请看https://www.cnblogs.com/cwjr/p/13230091.html

    #include<bits/stdc++.h>
    using namespace std;
    const long long N=1e5*3;
    long long c[N],ans,n,m,num;
    long long lowbit(long long x){
        return x&(-x);
    }
    void insert(long long x,long long vol){
        while(x<=N){
            c[x]+=vol;
            x+=lowbit(x);
        }
    }
    long long ask(long long x){
        long long sum=0;
        while(x){
            sum+=c[x];
            x-=lowbit(x);
        }
        return sum;
    }
    int main(){
        cin>>n>>m;
        //树状数组下标整体加上n+1,防止出现负数 
        insert(n+1,1); //把0加入树状数组,请c思考why 
        for(long long i=1;i<=n;i++)
        {
            long long x;
            cin>>x;
            if(x>=m)
            num++;
            else num--;
            ans+=ask(num+n+1);
            insert(num+n+1,1); 
        }
        cout<<ans;
    }
  • 相关阅读:
    Java Native Method
    SQL语句优化
    Ibatis的环境搭建以及遇到的问题解决
    Java 构建器
    SpringMVC自定义视图 Excel视图和PDF视图
    java 枚举的常见使用方法
    mysql 根据某些字段之和排序
    MFC The Screen Flickers When The Image Zoomed
    How To Debug Qmake Pro File
    Gcc And MakeFile Level1
  • 原文地址:https://www.cnblogs.com/cwjr/p/13279641.html
Copyright © 2011-2022 走看看