首页 > 其他分享 >中位数(权值线段树版)

中位数(权值线段树版)

时间:2024-07-11 23:31:30浏览次数:18  
标签:le nums int 样例 中位数 权值 树版 100

中位数

题目描述

给定一个长度为 N N N 的非负整数序列 A A A,对于前奇数项求中位数。

输入格式

第一行一个正整数 N N N。

第二行 N N N 个正整数 A 1 … N A_{1\dots N} A1…N​。

输出格式

共 ⌊ N + 1 2 ⌋ \lfloor \frac{N + 1}2\rfloor ⌊2N+1​⌋ 行,第 i i i 行为 A 1 … 2 i − 1 A_{1\dots 2i - 1} A1…2i−1​ 的中位数。

样例 #1

样例输入 #1

7
1 3 5 7 9 11 6

样例输出 #1

1
3
5
6

样例 #2

样例输入 #2

7
3 1 5 9 8 7 6

样例输出 #2

3
3
5
6

提示

对于 20 % 20\% 20% 的数据, N ≤ 100 N \le 100 N≤100;

对于 40 % 40\% 40% 的数据, N ≤ 3000 N \le 3000 N≤3000;

对于 100 % 100\% 100% 的数据, 1 ≤ N ≤ 100000 1 \le N ≤ 100000 1≤N≤100000, 0 ≤ A i ≤ 1 0 9 0 \le A_i \le 10^9 0≤Ai​≤109。

代码

//权值线段树求中位数

#include<iostream>
#include<algorithm>
#include<cstring>
#include<vector>

using namespace std;

const int N = 1e5+10;

struct E{
    int l,r,cnt;
}tr[N<<2];

int n;
int w[N];
vector<int>nums;

int get(int x){
    return lower_bound(nums.begin(),nums.end(),x)-nums.begin();
}

void pushup(int u){
    tr[u].cnt=tr[u<<1].cnt+tr[u<<1|1].cnt;
}

void update(int u,int l,int r,int x){
    if(l==r){
        tr[u].cnt++;
        return; 
    }
    
    int mid=l+r>>1;
    
    if(x<=mid)update(u<<1,l,mid,x);
    else update(u<<1|1,mid+1,r,x);
    
    pushup(u);
    
}

int query(int u,int l,int r,int k){
    if(l==r){
        return nums[l];
    }
    
    int mid=l+r>>1;
    
    int c=tr[u<<1].cnt;
    if(k<=c)return query(u<<1,l,mid,k);
    return query(u<<1|1,mid+1,r,k-c);
}

int main(){
    cin>>n;
    
    for(int i=1;i<=n;i++){
        cin>>w[i];
        nums.push_back(w[i]);
    }
    
    sort(nums.begin(),nums.end());
    nums.erase(unique(nums.begin(),nums.end()),nums.end());
    
    int tot=nums.size();
    for(int i=1,k=1;i<=n;i+=2,k++){
        if(i>1)update(1,0,tot-1,get(w[i-1]));
        update(1,0,tot-1,get(w[i]));
        cout<<query(1,0,tot-1,k)<<endl;
    }
    
    return 0;
}

标签:le,nums,int,样例,中位数,权值,树版,100
From: https://blog.csdn.net/m0_60738889/article/details/140361896

相关文章

  • P7382 [COCI2018-2019#6] Simfonija (中位数)
    P7382[COCI2018-2019#6]Simfonija中位数不妨设\(C_i=A_i-B_i\),那么操作后的代数式可以写成:\[\sum\limits_{i=1}^n|C_i+x|\]如果\(k=0\),那么\(x\)的取值就是一个经典问题了,即\(C\)序列的中位数(偶数取中间任意)。如果\(k\ne0\),要使答案最小,就是将\(k\)个数的代价变......
  • 中位数
     importjava.util.*;​publicclassMain{    staticint[]a;  staticint[]b;  static intl;  publicstaticvoidmain(String[]args){    Scannersc=newScanner(System.in);    l=sc.nextInt();    a=......
  • C++算法实践04-寻找两个正序数组的中位数
    一、题目:给定两个大小分别为 m 和 n 的正序(从小到大)数组 nums1 和 nums2。请你找出并返回这两个正序数组的 中位数 。算法的时间复杂度应该为 O(log(m+n)) 。示例1:输入:nums1=[1,3],nums2=[2]输出:2.00000解释:合并数组=[1,2,3],中位数2示例2:输入:nu......
  • [学习笔记] 动态开点权值线段树合并 - 数据结构
    权值线段树例题【模板】普通平衡树#include<bits/stdc++.h>usingnamespacestd;constintN=1e5+1;intn,val[N],opt[N],num[N],cnt,len,san[N],m[N],rnk[N];unordered_map<int,int>dfn;structWeightedSegmentTree{ #definels(id<<1) #define......
  • 数理统计(数值修约、0.5修约、0.2修约、有效数字运算、平均值、中位数、极差、标准差
    数理统计(数值修约、0.5修约、0.2修约、有效数字运算、平均值、中位数、极差、标准差、变异系数)原文:数理统计(数值修约、0.5修约、0.2修约、有效数字运算、平均值、中位数、极差、标准差、变异系数)_修约到0.5怎么修约-CSDN博客一、数值修约:口诀:四舍六入五考虑,五后非零则进......
  • Leecode热题100---二分查找--4:寻找两个正序数组的中位数
    题目:给定两个大小分别为m和n的正序(从小到大)数组nums1和nums2。请你找出并返回这两个正序数组的中位数。解法1、暴力解法(归并)思路:合并nums1,nums2为第三个数组排序第三个数组按下标,找出中位数classSolution{public: doublefindMedianSortedArrays(vec......
  • 4. 寻找两个正序数组的中位数
    给定两个大小分别为m和n的正序(从小到大)数组nums1和nums2。请你找出并返回这两个正序数组的中位数。算法的时间复杂度应该为O(log(m+n))。示例1:输入:nums1=[1,3],nums2=[2]输出:2.00000解释:合并数组=[1,2,3],中位数2示例2:输入:nums1=[1,2],nums2=......
  • hdu4417(权值离散化后建立主席树)
    Problem-4417(hdu.edu.cn)马里奥是举世闻名的水管工。他“魁梧”的身材和惊人的跳跃能力让我们想起了。现在可怜的公主又遇到了麻烦,马里奥需要拯救他的爱人。我们将通往老板城堡的道路视为一条线(长度为n),在每个整数点i上都有一块高度为hi的砖。现在的问题是,如果马里奥可......
  • 4-寻找两个正序数组的中位数
    题目:两个正序数组,找出他们的中位数(中间位置的数),算法的时间复杂度应该为O(log(m+n))。1.将两个数组组成一个新的数组,int[]allArry=newint[nums1.length+nums2.length];System.arraycopy(nums1,0,allArry,0,nums1.length);System.arraycopy(nums2,0,allArry,num......
  • 【每日一题】寻找两个正序数组的中位数
    4.寻找两个正序数组的中位数给定两个大小分别为m和n的正序(从小到大)数组 nums1和 nums2。请你找出并返回这两个正序数组的中位数。算法的时间复杂度应该为O(log(m+n))。示例1:输入:nums1=[1,3],nums2=[2]输出:2.00000解释:合并数组=[1,2,3],中位数2示例......