csp-s模拟测试52平均数,序列题解

题面:https://www.cnblogs.com/Juve/articles/11602244.html

平均数:

第k个平均数不好求,我们考虑二分,转化成平均数小于x的有几个

虑把序列中的每个数减去 x,则我们只需求区间和小于 0 的区间数量。

我们对这个序列求前缀和,则区间[L,R]和小于 0 当且仅当 SL-1>SR,

答案即为前缀和序列 S 的逆序对数量,使用经典的归并排序即可解决

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<queue>
#define int long long
#define double long double
using namespace std;
const int MAXN=1e5+5;
int n,k,ans=0;
double L=0.0,R=1e9+1,sum[MAXN],temp[MAXN],res,a[MAXN];
double max(double a,double b){
    return a>b?a:b;
}
void merge_sort(int l,int r){
    int mid,i,j,k;
    if(l==r) return;
    mid=(l+r)/2;
    merge_sort(l,mid);merge_sort(mid+1,r);
    i=l;j=mid+1;k=l;
    while(i<=mid&&j<=r){
        if(sum[i]>sum[j]){
            ans+=mid-i+1;
            temp[k]=sum[j];
            j++;  
            k++;
        }else
            temp[k]=sum[i];
            i++;
            k++;
        }
    }
    while(i<=mid){
        temp[k]=sum[i]; 
        i++; 
        k++;
    }
    while(j<=r){  
        temp[k]=sum[j]; 
        j++; 
        k++;
    }
    for(i=l;i<=r;i++)
        sum[i]=temp[i];
}
bool check(double x){
    ans=0;
    sum[0]=0;
    for(int i=1;i<=n;++i){
        sum[i]=sum[i-1]+a[i]-x;
    }
    merge_sort(0,n);
    return ans<k;
}
signed main(){
    scanf("%lld%lld",&n,&k);
    for(int i=1;i<=n;++i){
        scanf("%Lf",&a[i]);
    }
    while(L<R-(1e-5)){
        double mid=(L+R)/2.0;
        if(check(mid)) L=mid;
        else R=mid;
    }
    printf("%0.4Lf\n",L);
    return 0;
}

序列:

考虑主席树,相当与对每一个位置建一棵动态开点权值线段树,

我们不能把所有区间插进去,我们插入询问,对于每一个位置,经过它的询问有很多,我们统计a[i]对整个答案的贡献

我们对每一个位置插入所有在这个位置上要查询的x,然后答案就是对于每一个位置i,在i所在的线段树中找小于a[i]的x的数量,这是a[i]对整个答案的贡献

修改后我们还像之前那样查询,如果将p位置更改为v,那么减去a[p]的贡献,在加上更改后的v对整个答案的贡献

 

posted @   xukl21  阅读(190)  评论(0编辑  收藏  举报
编辑推荐:
· 如何在 .NET 中 使用 ANTLR4
· 后端思维之高并发处理方案
· 理解Rust引用及其生命周期标识(下)
· 从二进制到误差:逐行拆解C语言浮点运算中的4008175468544之谜
· .NET制作智能桌面机器人:结合BotSharp智能体框架开发语音交互
阅读排行:
· Cursor预测程序员行业倒计时:CTO应做好50%裁员计划
· 想让你多爱自己一些的开源计时器
· 大模型 Token 究竟是啥:图解大模型Token
· 用99元买的服务器搭一套CI/CD系统
· 如何在 .NET 中 使用 ANTLR4
点击右上角即可分享
微信分享提示