首页 > 其他分享 >求中位数应经常联想到二分

求中位数应经常联想到二分

时间:2024-10-25 20:47:38浏览次数:6  
标签:二分 x% ll 中位数 2500000 联想 include mod

题目链接:https://codeforces.com/contest/2008/problem/H

首先想了一会,随后想到了取模,但是由于这个q太大于是考虑是否可以实现动态变化最后还是没得出结果,遂看了题解。
原来这道题由于n的限制,所以可以对求出取模所对应的余数的取模区间
\([k*x,k*x+m]\),于是复杂度到了\(nlogn\)(前缀和预处理),随后怎么去找这个中位数呢?二分!,然后复杂度
就到了\(n*logn*logn\)。联想到今年icpc网络赛的的一道求中位数的题,中位数的求法大概率是与中位数一起考察的,这点得牢记

#include<iostream>
#include<queue>
#include<map>
#include<set>
#include<vector>
#include<algorithm>
#include<deque>
#include<cctype>
#include<string.h>
#include<math.h>
#include<time.h>
#include<random>
#include<stack>
#include<string>
#define ll                                    long long 
#define lowbit(x) (x & -x)
using namespace std;
mt19937 rnd(time(0));
const ll mod=1e9+7;
const ll N=2e5+5;
ll ksm(ll x,ll y)
{
	ll ans=1;
	while(y)
	{
		if(y&1)
		ans=(ans%mod*x%mod)%mod;
		x=x%mod*(x%mod)%mod;
		y>>=1;
	}
	return ans%mod%mod;
}
ll gcd(ll x,ll y)
{
	if(y==0)
	return x;
	else 
	return gcd(y,x%y);
}
void fio()
{
		ios::sync_with_stdio(0);
		cin.tie(0);
		cout.tie(0);
}
ll a[2500000];
ll pre[2500000];
ll d[2500000];
bool vis[2500000];
int main()
{
	ll t;
	cin>>t;
	while(t--)
	{
	ll n,q;
	cin>>n>>q;
	map<ll,ll>f;
	for(ll i=1;i<=n;i++)cin>>a[i],f[a[i]]++;
	for(ll i=1;i<=n;i++)pre[i]=pre[i-1]+f[i],vis[i]=0,d[i]=0;//O(1)
	while(q--)
	{
		ll x;
		cin>>x;
		if(vis[x]>0)
		{
		cout<<d[x]<<" ";
		continue;
		}
		ll l=0,r=x-1;
		while(l<r)
		{
			ll mid=(l+r)>>1;
			ll ans=0;
		for(ll k=1;k*x<=n;k++)
		{
			ll l1=k*x;
			ll r2=min(k*x+mid,n);
			ans+=pre[r2]-pre[l1-1];
		}
		ans+=pre[mid];
		//<=mid的有
		//cout<<mid<<endl;
		//cout<<ans<<endl;
		if(ans>=n/2+1)
		{
			r=mid;
		}
		else l=mid+1;
		}
		cout<<r<<" ";
		d[x]=r;
		vis[x]=1;
	}
	cout<<endl;
	}

}

标签:二分,x%,ll,中位数,2500000,联想,include,mod
From: https://www.cnblogs.com/cjcf/p/18503259

相关文章

  • E71 树形DP+二分 P3523 [POI2011] DYN-Dynamite
    视频链接:   P3523[POI2011]DYN-Dynamite-洛谷|计算机科学教育新生态//树形DP+二分O(nlogn)#include<iostream>#include<cstring>#include<algorithm>usingnamespacestd;intread(){intx=0,f=1;charc=getchar();while(c>'9'||c......
  • 二分图的判别(染色法、匈牙利算法)
    二分图的判别:首先二分图是指一个图如果没有奇数环,则该图是二分图。其实这两种算法都是基于dfs来做的,要深刻理解每个算法的dfs指代的是什么。1、染色法:所谓的染色是指所有边的每一条边的两个端点颜色不同,算法思路就是让每个顶点都做一次dfs,判断其中有无同一条边的端点颜色相同。......
  • wqs二分
    感觉一般可能要严谨证明的话还是有点麻烦,不如直接打表,或者先老实WA一发来的快一般题目会有选恰好k个/次这样的限制大致就是通过二分斜率,然后通过dp,或者贪心计算出最大/最小值,然后通过判断这个最大/最小值对应的选的个数来调整需要注意的是,我们计算的相当于是截距,还要+/-kl才......
  • P2839 [国家集训队] middle(二分+可持久化线段树)
    P2839[国家集训队]middle二分+可持久化线段树中位数经典做法,二分答案,将小于的部分看做\(-1\),大于等于的部分看做\(+1\),那么答案可以更大的条件就是区间和大于等于\(0\)(等于\(0\)可不可以取到看是下取整还是上取整,本题是上取整)。那么问题就是怎么判断有没有这样一个区间......
  • 二分图
    二分图速通定义若一个无向图\(G=(V,E)\)的点集\(V\)可以分解成两个互不相交的子集\(A,B\),且对于所有边\((i,j)\)的端点\(i,j\)都分别属于子集\(A,B\)中的元素,则称\(G\)是一个二分图。判定一张无向图是二分图,当且仅当图中不存在奇环。故我们有染色算法判定二分图......
  • 二分图
    二分图概念假设\(G=(V,E)\)是一个无向图,若点集\(V\)可以分解成互不相交的子集\((A,B)\),并且图中所有边\((i,j)\)的端点\(i\)、\(j\)分别属于子集\(A\)、\(B\),则称\(G\)是一个二分图定理:一张无向图时二分图,当且仅当图中不存在奇环。染色法判定一个图是否是二分图......
  • 二分图学习笔记
    1.概念假设图\(G=(V,E)\)是无向图,若顶点集\(V\)可以分成两个互不相交的子集\((A,B)\),且任意边\((i,j)\)两端点分别属于两子集,则图\(G\)是二分图判断方法:染色法匹配:无公共点的边集匹配数:边集中边的个数最大匹配:匹配数最大的匹配增广路:设M是一个匹配,如果存在一条连接两个未匹......
  • 二分算法
    今天学了二分算法:在一个有序的列表里找一个数,用for循环,每次比较中间的数和要找的数,要找的数大则将头移到中间的数的下一个数,否则将尾移到中间的数。(头算尾不算)这是代码:#include<bits/stdc++.h>usingnamespacestd;inta[100001];intbs(inta[],intl,intr,intx){ i......
  • Dilworth 定理与二分图部分理论
    给定一个DAG,定义链:一条链内任意两点之间都存在一条路径反链:任意两点都不存在路径Dilworth定理:最长反链\(=\)最小链覆盖。最小链覆盖内一个点只能归属于一条链,但链不一定是连续的。事实上这个还能转化为“选出若干条(一般定义下的)链,但一个点可以在多条链内”,本质相同。......
  • P11217 【MX-S4-T1】「yyOI R2」youyou 的垃圾桶(线段树上二分)
    link赛时是想到普通的线段树+二分\(O(q\log^2n)\),预期是70pts,实际50pts后面发现又是在longlong类型的计算中,1ll写成了1,然后爆负数,复杂度就错了,T了四个点开题,读起来是一个很套路的题目要对区间在线修改,区间加、(区间乘?),发现数据很大,那就是线段树、树状数组维护了思......