median(NOIP模拟赛Round 3)

本文介绍了一种使用线性算法解决特定中位数问题的方法,通过寻找序列的中位数并利用前缀和及动态规划技巧,有效地统计了符合条件的子序列数量。

也是神奇的题目。。

原题传送门

首先看到这道题目,很明显我们需要线性算法

1、前缀和+统计

2、DP+统计

对于第一种算法,我们可以对于任何一个a[i]对b进行比较,如果大于b标上1,等于b标上0,小于b标上-1;

以0为中介,前缀和前后展开统计答案即可。。学长的神奇做法,不讲。。

第二种算法啊,,

其实和第一种算法差不多

首先我们找到中位数b

对其左边和右边进行搜索

对于右边if(a[i]>a[i-1])f[i]=f[i-1]+1;else f[i]=f[i-1]-1;

左边同上,不过i-1改为i+1。。(水~)

然后我们很快会想到如果我们发现f[a[p](a[p]=b)]=f[i]=0时,答案肯定要+1。。这个很好理解吧。。

那么我们发现其实中位数序列的起点或终点不一定一定是a[p]

所以我们再对于每一次出现的f[i]做一下统计

即if(f[i])tot[0][0][f[i]]++;else tot[0][1][-f[i]]++;(统计另一边的时候要写成f[i]>=0!注意!这非常重要!,因为前段的0归为负数,后端的0就要归为正数!,否则统计会出错!)

第一个维度是记录在a[p]左还是右边,第二个维度是记录是否为负数。。由于C++没有负数数组,所以不加会RE。

然后判断的时候如果发现(tot[0][0][i]&&tot[1][1][i])||(tot[0][1][i]&&tot[1][0][i])

显然我们的答案就是左边端点数*右边端点数

然后就是代码啦!

#include<iostream>
#include<cstdio>
using namespace std;
int n,b,now;
unsigned long long ans;
int a[100001];
int f[100001];
int cnt[3][2][100001];
int main(){
    freopen("median.in","r",stdin);
    freopen("median.out","w",stdout);
    scanf("%d%d",&n,&b);
    for(int i=1;i<=n;i++)
    {
        scanf("%d",&a[i]);
        if(a[i]==b)now=i;
    }
    for(int i=now+1;i<=n;i++)
    {
        if(a[i]>b)f[i]=f[i-1]+1;
        else f[i]=f[i-1]-1;
        if(f[i]>=0)cnt[1][0][f[i]]++;
        else cnt[1][1][-f[i]]++;
    }
    for(int i=now-1;i>=1;i--)
    {
        if(a[i]>b)f[i]=f[i+1]+1;
        else f[i]=f[i+1]-1;
        if(f[i]>0)cnt[2][0][f[i]]++;
        else cnt[2][1][-f[i]]++;    
    }
    for(int i=1;i<=n;i++)if(f[i]==0)ans++;
    for(int i=0;i<=n-1;i++)
    {
        if(cnt[1][0][i]&&cnt[2][1][i])ans+=cnt[1][0][i]*cnt[2][1][i];
        if(cnt[1][1][i]&&cnt[2][0][i])ans+=cnt[1][1][i]*cnt[2][0][i];
    }
    printf("%lld\n",ans);
    fclose(stdin);
    fclose(stdout); 
}

 

转载于:https://www.cnblogs.com/ghostfly233/p/6901135.html

### 中位数加三倍四分位距的计算与解释 在统计学中,中位数(median)和四分位距(IQR)是描述数据集中趋势和离散程度的重要指标。中位数加三倍四分位距(median + 3 × IQR)是一种扩展的统计方法,用于识别数据集中的极端异常值或评估数据分布的尾部行为。 中位数是将数据集按大小顺序排列后位于中间的值,它能够有效反映数据的中心位置,尤其在数据分布不对称或存在异常值时,比均值更具稳健性。四分位距(IQR)则是第三四分位数(Q3)与第一四分位数(Q1)之差,用于衡量数据中间50%部分的范围。计算公式为:IQR = Q3 − Q1[^1]。 在实际应用中,median + 3 × IQR 可以作为识别极端异常值的上限阈值。通常情况下,数据点如果超过该阈值,则可能被视为极端异常值。这一方法在数据清洗、异常检测和质量控制等领域具有重要意义。 ```scala // Scala示例:计算median + 3 × IQR object Statistics { def median(xs: Vector[Double]): Double = xs(xs.size / 2) def quartiles(xs: Vector[Double]): (Double, Double, Double) = { val sorted = xs.sorted val q1 = sorted(sorted.size / 4) val q3 = sorted(sorted.size / 4 * 3) (q1, median(sorted), q3) } def iqr(xs: Vector[Double]): Double = quartiles(xs) match { case (lowerQuartile, _, upperQuartile) => upperQuartile - lowerQuartile } def upperExtremeThreshold(xs: Vector[Double]): Double = median(xs) + 3 * iqr(xs) } ``` median + 3 × IQR 的计算方法相较于 median + 1.5 × IQR 更加严格,适用于对极端值敏感的场景,例如金融数据分析、网络安全监测等。通过设定更高的阈值,可以更有效地筛选出可能对模型训练或分析结果产生显著影响的极端值。 在解释 median + 3 × IQR 时,需要注意其与数据分布形态的关系。如果数据呈现对称分布,median + 3 × IQR 可能对应于数据尾部的极值范围;而在偏态分布中,该阈值可能无法准确反映极端值的边界,因此需要结合其他统计量(如偏度、峰度)进行综合分析。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值