HDU 5701 中位数计数(数论)

题目链接:http://acm.hdu.edu.cn/viewcode.php?rid=17615323

位数定义为所有值从小到大排序后排在正中间的那个数,如果值有偶数个,通常取最中间的两个数值的平均数作为中位数。

现在有n个数,每个数都是独一无二的,求出每个数在多少个包含其的区间中是中位数。

题目大意:给你1-n一共n个数,让你枚举所有区间,找出每个区间的中位数,最后输出每个数一共当了多少次中位数

解题思路:
最暴力的想法肯定是枚举所有区间,通过排序找出所有区间的中位数,时间复杂度n^3log(n)。
队友提醒了一下可以不用排序,直接用线段树找第k大,复杂度n^2*log(n),依旧会超时。
关键耗时是在枚举区间上,其实可以根据中位数的性质更优雅的枚举所有区间。
假设Trb和Trs分别是数i右边比i大的和比i小的数的个数,Tlb和Tls分别是数i左边比数i大的和比i小的个数,假设i在这个区间中为中位数,则
Trb-Trs=Tls-Tlb;
因为Trb+Tlb=Trs+Tls(比i大的数等于比i小的数)

所以我们可以先向右边扩展,找出所有Trb-Trs值并用数组记录,再向左边扩展,找出所有Tls-Tlb,如果数组中有对应的值就在答案中相加,注意相减为0的情况要特殊处理一下。

AC 代码:

#include <iostream>
#include <cstring>
#include <cstdio>
#define RI(N) scanf("%d",&(N))
#define RII(N,M) scanf("%d %d",&(N),&(M))
#define RIII(N,M,K) scanf("%d %d %d",&(N),&(M),&(K))
#define mem(a) memset((a),0,sizeof(a))
using namespace std;
const int inf=1e9;
const int inf1=-1*1e9;
double EPS=1e-10;
typedef long long LL;

int a[8005];

int b[8005*2];

int main()
{
    int n;

    while(RI(n)!=EOF)
    {
        for(int i=0;i<n;i++)
        RI(a[i]);
        for(int i=0;i<n;i++)
        {
            memset(b,0,sizeof(b));
            int ans=0;
            int sta=8000;

            int ex=0;
            for(int j=i+1;j<n;j++)
            {

                if(a[j]>a[i]) ex++;
                else ex--;
                b[sta+ex]++;
            }
            ex=0;

            for(int j=i-1;j>=0;j--)
            {

                if(a[j]>a[i]) ex++;
                else ex--;
                ans+=b[sta-ex];
                if(ex==0) ans++;
            }

            ans+=(b[sta]+1);
            if(i!=n-1) printf("%d ",ans);
            else printf("%d",ans);
        }
        printf("\n");


    }



    return 0;
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值