k小数查询(前缀和)

Posted Harris-H

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了k小数查询(前缀和)相关的知识,希望对你有一定的参考价值。

k小数查询(前缀和)

把小于等于 x x x的数置为 1 1 1,则答案求区间内包含 x x x 1 1 1的个数为 k k k的区间。

先可以找到 x x x的位置 p o s pos pos,同时预处理 1 1 1的前缀和。

然后开一个桶,用来储存 [ p o s , n ] [pos,n] [pos,n]范围前缀和的个数。

然后枚举区间 l ∈ [ 1 , p o s ] l\\in [1,pos] l[1,pos]

每次的贡献就是: b [ p r e [ i − 1 ] + k ] b[pre[i-1]+k] b[pre[i1]+k]

时间复杂度: O ( n ) O(n) O(n)

// Problem: k小数查询
// Contest: NowCoder
// URL: https://ac.nowcoder.com/acm/contest/11177/B
// Memory Limit: 524288 MB
// Time Limit: 2000 ms
// Date: 2021-08-22 20:27:31
// --------by Herio--------

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull; 
const int N=2e5+5,M=2e4+5,inf=0x3f3f3f3f,mod=1e9+7;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define ios ios::sync_with_stdio(false),cin.tie(0) 
void Print(int *a,int n){
	for(int i=1;i<n;i++)
		printf("%d ",a[i]);
	printf("%d\\n",a[n]); 
}
int a[N],b[N];
int main(){
	int n,x,k,pos;scanf("%d%d%d",&n,&x,&k);
	ll ans=0;
	for(int i=1;i<=n;i++){
		int y;scanf("%d",&y);
		if(y==x) pos=i;
		a[i]=a[i-1]+(y<=x);
	}
	for(int i=pos;i<=n;i++) b[a[i]]++;
	for(int i=1;i<=pos;i++) ans+=b[a[i-1]+k];
	printf("%lld\\n",ans);
	return 0;
}

以上是关于k小数查询(前缀和)的主要内容,如果未能解决你的问题,请参考以下文章

kotlin-从一个片段更改多个片段的小数位

OJ2130K小数查询

树状数组区间加+区间查询模板洛谷P3372

leetcode_1292. Maximum Side Length of a Square with Sum Less than or Equal to Threshold_[二维前缀和](代码片段

leetcode-序列和为K的数量-对前缀和和哈希代码的分析

leetcode-序列和为K的数量-对前缀和和哈希代码的分析