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

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

平均数:

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

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

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

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

#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对整个答案的贡献

#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<vector>
#define int long long
#define re register
using namespace std;
const int MAXN=1e5+5;
int n,m,q,a[MAXN],ans,x[MAXN];
int root[MAXN],tot=0,ls[MAXN<<6],rs[MAXN<<6],tr[MAXN<<6];
struct node{
	int pos,val;
};
vector<node>v[MAXN];
inline void insert(re int &k,re int pre,re int l,re int r,re int pos,re int val){
	k=++tot;
	ls[k]=ls[pre],rs[k]=rs[pre],tr[k]=tr[pre];
	if(l==r){
		tr[k]+=val;
		return ;
	}
	re int mid=(l+r)>>1;
	if(pos<=mid) insert(ls[k],ls[pre],l,mid,pos,val);
	else insert(rs[k],rs[pre],mid+1,r,pos,val);
	tr[k]=tr[ls[k]]+tr[rs[k]];
}
inline int query(re int k,re int l,re int r,re int opl,re int opr){
	if(opl<=l&&r<=opr) return tr[k];
	re int mid=(l+r)>>1,res=0;
	if(opl<=mid) res+=query(ls[k],l,mid,opl,opr);
	if(opr>mid) res+=query(rs[k],mid+1,r,opl,opr);
	return res;
}
signed main(){
	scanf("%lld%lld%lld",&n,&m,&q);
	for(re int i=1;i<=n;++i){
		scanf("%lld",&a[i]);
	}
	for(re int i=1,l,r;i<=m;++i){
		scanf("%lld%lld%lld",&l,&r,&x[i]);
		v[l].push_back((node){x[i],1});
		v[r+1].push_back((node){x[i],-1});
	}
	for(re int i=1;i<=n;++i){
		root[i]=root[i-1];
		int N=v[i].size();
		for(re int j=0;j<N;++j){
			insert(root[i],root[i],1,n,v[i][j].pos,v[i][j].val);
		}
	}
	for(re int i=1;i<=n;++i){
		ans+=query(root[i],1,n,1,a[i]);
	}
	printf("%lld\n",ans);
	for(re int i=1,p,v;i<=q;++i){
		scanf("%lld%lld",&p,&v);
		p^=ans,v^=ans;
		ans+=(query(root[p],1,n,1,v)-query(root[p],1,n,1,a[p]));
		a[p]=v;
		printf("%lld\n",ans);
	}
	return 0;
}

原文地址:https://www.cnblogs.com/Juve/p/11602405.html

时间: 2024-11-06 03:37:00

csp-s模拟测试52平均数,序列题解的相关文章

【基础练习】【数论/模拟】codevs1670 无穷的序列题解

文章被盗还是很严重,加版权信息 转载请注明出处 [ametake版权所有]http://blog.csdn.net/ametake欢迎来看看 题目: 题目描述 Description 有一个无穷序列如下: 110100100010000100000- 请你找出这个无穷序列中指定位置上的数字 输入描述 Input Description 第一行一个正整数N,表示询问次数: 接下来的N行每行一个正整数Ai,Ai表示在序列中的位置. 输出描述 Output Description N行,每行为0或1,

模拟测试52,53反思

这两次考试都挂了不少分,也学到了很多东西. 52 T1 常数写大正解T成暴力 T2 数组越界70->50又由于我的智障操作最后一秒50->20 53 T2 逆推打成正推100->21 T3 暴力56pts,错解57pts,机智的我交了暴力,还把数组开小了57->43. 1.虽然不同算法的理论复杂度是一样的,但是常数真的很重要!map常数很大! 2.在不确定自己打的是对的时候,不要在最后时刻交代码. 3.期望逆着推,其实不是期望,对于最优决策来说,要么枚举所有决策, 判断优劣,要么先

2019.9.26 csp-s模拟测试52 反思总结

刚刚写了一个小时的博客没了,浏览器自动刷新. 一!个!小!时! 鼠标键盘电脑哪个都不能摔,气死我了. 垃圾选手T1T2没思路,T3倒是想出来得比较早,靠T3撑着分数. 数据结构学傻选手,属实垃圾. T1平均数: 一个序列的所有数如果减去x,那么平均数也会减去x.可以二分这个x,统计序列里平均数小于0的序列的个数,含义为原序列平均数小于x的序列的个数.最后统计值小于k且最接近k的x就是所求答案. 序列的平均数小于0,那么序列的和也一定小于0.表现在前缀和上即为一个区间的sumr<suml-1,转化

2018-10-25 模拟测试题解

目录 问题 A: 魏传之长坂逆袭 题目描述 输入 输出 样例输入 样例输出 题解 问题 B: 蜀传之单刀赴会 题目描述 [问题描述] 输入 输出 样例输入 样例输出 题解 问题 C: 吴传之火烧连营 [题目背景] [问题描述] 输入 输出 样例输入 样例输出 [样例解释] [数据规模和约定] 题解 本篇题解也发表于zwcblog作者是同一个人 问题 A: 魏传之长坂逆袭 题目描述 众所周知,刘备在长坂坡上与他的一众将领各种开挂,硬生生从曹操手中逃了出去,随后与孙权一起火烧赤壁.占有荆益.成就霸业

2018冬令营模拟测试赛(三)

2018冬令营模拟测试赛(三) [Problem A]摧毁图状树 试题描述 输入 见"试题描述" 输出 见"试题描述" 输入示例 见"试题描述" 输出示例 见"试题描述" 数据规模及约定 见"试题描述" 题解 这题没想到贪心 QwQ,那就没戏了-- 贪心就是每次选择一个最深的且没有被覆盖的点向上覆盖 \(k\) 层,因为这个"最深的没有被覆盖的点"不可能再有其它点引出的链覆盖它了,而它又

2018冬令营模拟测试赛(五)

2018冬令营模拟测试赛(五) [Problem A][UOJ#154]列队 试题描述 picks 博士通过实验成功地得到了排列 \(A\),并根据这个回到了正确的过去.他在金星凌日之前顺利地与丘比签订了契约,成为了一名马猴烧酒. picks 博士可以使用魔法召唤很多很多的猴子与他一起战斗,但是当猴子的数目 \(n\) 太大的时候,训练猴子就变成了一个繁重的任务. 历经千辛万苦,猴子们终于学会了按照顺序排成一排.为了进一步训练,picks 博士打算设定一系列的指令,每一条指令 \(i\) 的效果

[考试反思]0929csp-s模拟测试55:沦陷

菜得过分. 面对T1的大板子不知所措,然后T2的贪心不小心把排序语句删了... T1这种大模板啊...其实我是觉得我能打出来的,然后先用一个小时码了一个2k. 然后做T2想贪心就出来了.十分钟码完T3暴力之后回T1打对拍瞬间爆炸. 于是又重新打了一个2k,WA0.对拍发现. 然后考试就没几分钟了交暴力走了. 不要打完就跑,记得早点对拍改进思路. T1: 的确是挺裸的线段树.离散化或者权值线段树都可以. 但是考场上两个都打出来都死了. 最后用离散化A的. 1 #include<cstdio> 2

csp-s模拟测试93

csp-s模拟测试93 自闭场. $T1$想到$CDQ$,因为复杂度少看见一个$0$打了半年还用了$sort$直接废掉,$T2$,$T3$直接自闭暴力分都没有.考场太慌了,心态不好. 80 02:07:34 0 03:12:11 0 03:11:53 80 03:12:11 没有前途就是垃圾趁早滚回实验二安度晚年吧. A. 序列 $CDQ$不接受反驳. B. 二叉搜索树 最简单的$Dp$都没认真想,太垃圾了,积累一个决策单调性优化$Dp$.一些看似是$n^3$的题可以通过特殊性质优化,还比如以前

微信在线信息模拟测试工具(基于Senparc.Weixin.MP)

目前为止似乎还没有看到过Web版的普通消息测试工具(除了官方针对高级接口的),现有的一些桌面版的几个测试工具也都是使用XML直接请求,非常不友好,我们来尝试做一个“面向对象”操作的测试工具. 测试工具在线DEMO:http://weixin.senparc.com/SimulateTool Senparc.Weixin.MP是一个开源的微信SDK项目,地址:https://github.com/JeffreySu/WeiXinMPSDK (其中https://github.com/Jeffrey