首页 > 其他分享 >整体二分

整体二分

时间:2024-07-27 12:39:20浏览次数:9  
标签:二分 int 询问 整体 mid num 数组 id

没啥好说的概念,直接看题目。

MKTHNUM - K-th Number

考虑如果我们对每个操作进行二分怎么做。

显然是对这个区间不大于二分值 \(mid\) 的数统计个数,看个数 \(num\) 和 \(k\) 的大小关系。如果 \(num\) 更大,证明 \(mid\) 大了,如果 \(num\) 更小,证明 \(mid\) 小了。

然后我们考虑推广这种思路。

首先我们询问的答案肯定是原来数组中的一个数,所以我们可以直接把原数组排序,然后用下标代表其权值。这里我们的排序事实上可以用离散化完成,那样做的效果相同,但是排序更方便。

接下来,我们要实现整体二分的核心函数 \(solve(l,r,L,R)\),表示当前对于编号为 \(id,id\in[l,r]\) 的询问,可能的答案为 \([L,R]\) 内的一个数。

当然,给出的询问不会这么巧合正好是上面那种情况的,所以我们在整体二分时需要对询问排序,当然这个后面会说。

因为答案在 \([L,R]\) 内,所以考虑找到中点 \(mid\),然后把下标在 \([L,mid]\) 内的数加到树状数组里(事实上如果权值不大可以加权值,但这题只能使用下标,要不然空间会炸)。

然后考虑如果对于一个询问 \((l,r,k)\),树状数组在 \([l,r]\) 内的数的数量 \(num\) 不小于 \(k\),证明对于这个询问 \(mid\) 太大了,把他扔到数组 \(q1\) 中;否则就是 \(mid\) 太小了,于是先 \(k-num\leftarrow k\),然后把这个询问扔到数组 \(q2\) 内。

这里说一下为什么要 \(k-num\leftarrow k\)。因为我们接下来对这类 \(mid\) 太小了的询问会单独处理,而后面统计的是在新区间内不大于他的数的数量。我们不能忽略之前比他小的数带来的贡献,所以要做这样一个操作。

然后做完这个类似于归并排序的操作后,我们把之前树状数组里的东西清空掉,然后把 \(q1,q2\) 数组内的东西放回询问数组接着递归处理(事实上就是做了个分类,然后对两类询问集训递归)。

边界情况:\(L=R\),此时 \([l,r]\) 内的询问的答案结尾 \(val_L\),注意不是 \(L\),因为我们一开始用下标代替了权值

代码:

#include<bits/stdc++.h>
#define int long long
#define N 100005
using namespace std;
int n,m,c[N],res[N];
struct node{
	int id,x;
	bool operator<(const node &t)const{
		return x<t.x;
	}
}a[N];
struct ask{
	int id,l,r,k;
}q[N],q1[N],q2[N];
int lowbit(int x){
	return x&-x;
}
void modify(int x,int v){
	while(x<=n){
		c[x]+=v;
		x+=lowbit(x);
	}
}
int qry(int x){
	int res=0;
	while(x){
		res+=c[x];
		x-=lowbit(x);
	}
	return res;
}
void solve(int l,int r,int L,int R){
	if(l>r)return;
	if(L==R){
		for(int i=l;i<=r;i++){
			res[q[i].id]=a[L].x;
		}
		return;
	}
	int mid=L+R>>1;
	for(int i=L;i<=mid;i++){
		modify(a[i].id,1);
	}
	int cnt1=0,cnt2=0;
	for(int i=l;i<=r;i++){
		int sum=qry(q[i].r)-qry(q[i].l-1);
		if(q[i].k<=sum){
			q1[++cnt1]=q[i];
		}
		else{
			q[i].k-=sum;
			q2[++cnt2]=q[i];
		}
	}
	for(int i=L;i<=mid;i++){
		modify(a[i].id,-1);
	}
	for(int i=1;i<=cnt1;i++){
		q[i+l-1]=q1[i];
	}
	for(int i=1;i<=cnt2;i++){
		q[i+l+cnt1-1]=q2[i];
	}
	solve(l,l+cnt1-1,L,mid);
	solve(l+cnt1,r,mid+1,R);
}
signed main(){
	cin>>n>>m;
	for(int i=1;i<=n;i++){
		cin>>a[i].x;
		a[i].id=i;
	}
	for(int i=1;i<=m;i++){
		cin>>q[i].l>>q[i].r>>q[i].k;
		q[i].id=i;
	}
	sort(a+1,a+n+1);
	solve(1,m,1,n);
	for(int i=1;i<=m;i++){
		cout<<res[i]<<'\n';
	}
	return 0;
}

标签:二分,int,询问,整体,mid,num,数组,id
From: https://www.cnblogs.com/zxh923aoao/p/18326775

相关文章

  • 二分图
    二分图定义:二分图是一种特殊的图,顶点被分为左右两部分,且两部分内没有连边。来源于oiwiki因为此图可以被分为两个集合,所以每条边链接的两个顶点都可以看作一个黑色,一个白色(如上图)。判定是否为二分图需要判断是否能分为两个集合可以用染色法。用深搜去遍历图,给每个顶点......
  • 如何学习Presto:糙快猛的大数据之路(建立整体框架)
    这个系列文章用"粗快猛+大模型问答+讲故事"的创新学习方法,让你轻松理解复杂知识!涵盖Hadoop、Spark、MySQL、Flink等大数据所有热门技术栈,每篇万字长文。时间紧?只看开头20%就能有收获!精彩内容太多?收藏慢慢看!点击链接开启你的大数据学习之旅https://blog.csdn.net/u012955829......
  • 2024年技校人工智能实验室建设及人工智能实训平台整体解决方案
    随着人工智能技术的迅猛发展,其在各行各业的应用日益广泛,对技能型人才的需求也急剧增长。为了满足这一市场需求,技校作为技能人才培养的重要基地,亟需加强人工智能领域的教育与实训。本文旨在提出《2024年技校人工智能实验室建设及人工智能实训平台整体解决方案》,以期为技校的......
  • 牛可乐与魔法封印----(二分)
     题目描述牛可乐得到了一个长度为n且非严格单调递增的序列 a,然而这个序列被q层魔法封印了,其中第i 层封印的问题包含两个整数xi,yi(xi≤yi),牛可乐必须正确回答序列中大于等于xi且小于等于yi​的数字个数才能够解开该层封印。牛可乐觉得这个问题太难了,于是他想请......
  • 深入剖析Tomcat整体架构
    目录Tomcat简介Tomcat架构概述核心组件详解ServerServiceConnectorEngineHostContextWrapper生命周期与初始化请求处理流程Tomcat的线程模型配置与优化常见问题与解决方案总结Tomcat简介ApacheTomcat是由Apache软件基金会开发的开源JavaWeb服务器和Servlet容器。它实......
  • 二分模块的相关性
    在寻找保持列表排序而不考虑插入和删除的方法时,我遇到了bisect和sortedcontainers模块。bisect的insort功能是O(n)因为它结合了bisect_leftO(logn)和|||然而,一个等效的操作insertO(n)defins......
  • 二分答案解题技巧
    二分答案有一个很显著的特征:一定存在一个临界值,单调性只是临界值的一种,而不是全部。临界值,就是寻找第一个/最后一个满足要求的值,这又分别对应着两个完全不同的二分模板,这里做题时推荐使用“第一个满足要求的值”,即对应着STL中的upper_bound,手写板对应着这篇文章里讲的模板......
  • 二分查找(数组的练习)
    一、什么是二分查找    二分查找(又叫折半查找)是一种查找算法,它能使查找的速度更快,但要求查找的序列必须有序。        如果我们按顺序在一个序列中查找一个数,当这个数在靠前的位置,查找的速度还好;那么当这个数在很靠后的位置呢?甚至是一个很长的数组,要查找......
  • 在设计电子产品时,如何平衡抗震和抗振需求以确保产品的整体性能?
            在电子产品的设计中,抗震和抗振需求是两个重要的考量因素,它们虽然在目标上有所重叠,即都是为了确保产品在各种使用环境下的可靠性和稳定性,但它们的侧重点和应对措施有所不同:抗震需求:定义:抗震需求通常指的是电子产品在设计时需要考虑到的抵抗外部冲击和震动的......
  • 二分图
    概念二分图是图论中的一个重要概念,指的是一个图的顶点集可以被分为两个互不相交的子集,并且图中的每条边都连接两个不同子集中的顶点。换句话说,如果一个图是二分图,那么可以将图中的所有顶点分为两组,使得每条边的两个端点分别属于不同的组。二分图当且仅当图中不含奇数环。判断......