• ARC 101 D


    题面在这里!

        这种题只能二分答案把qwwq,直接做根本做不了啊。。。

        首先你需要知道如何通过 一个区间<=x的数有多少个 来判断x和这个区间中位数的关系。

        很显然当数有至少 [L/2]+1 个(L是区间内数的个数)时,x>=该区间的中位数。

        你肯定觉得这多简单啊?有啥子用?

        第一,它可以转化成,区间内<=x的数比剩下的数多的时候,x>=该区间的中位数,于是就可以做二分里面套的部分。

        具体的来说,就是我们二分到一个x的时候,希望知道有多少个区间的中位数<=x。

        这个时候只需要把<=x的数设置成1,其他的设置成-1,然后算一算有多少区间的数的和是正数,这显然就是一个离散化+树状数组的傻逼问题。

        第二,它还可以用来作最外层的二分判断,调整二分的上下界。

        这个比较好想,我就不说了2333。

    #include<cstdio>
    #include<cstdlib>
    #include<algorithm>
    #include<cstring>
    #include<cmath>
    #define ll long long
    using namespace std;
    const int N=1e5+5;
     
    int n,m,f[N],ans,a[N],mid,b[N],c[N],ky;
    ll num;
     
    inline void update(int x,int y){ for(;x<=ky;x+=x&-x) f[x]+=y;}
    inline int query(int x){ int an=0; for(;x;x-=x&-x) an+=f[x]; return an;}
     
    inline ll calc(){
    	ll an=0;
    	b[0]=0,memset(f,0,sizeof(f));
    	for(int i=1;i<=n;i++) b[i]=b[i-1]+(a[i]<=mid?1:-1),c[i]=b[i];
    	c[ky=n+1]=0,sort(c+1,c+ky+1),ky=unique(c+1,c+ky+1)-c-1;
    	for(int i=0;i<=n;i++) b[i]=lower_bound(c+1,c+ky+1,b[i])-c;
    	
    	update(b[0],1);
    	for(int i=1;i<=n;i++) an+=(ll)query(b[i]-1),update(b[i],1);
    	
    	return an;
    }
     
    inline void solve(){
    	int L=1,R=1e9;
    	while(L<=R){
    		mid=L+R>>1;
    		if(calc()>=num) ans=mid,R=mid-1;
    		else L=mid+1;
    	}
    }
     
    int main(){
    	scanf("%d",&n),num=n*(ll)(n+1)>>1,num=(num>>1)+1;
    	for(int i=1;i<=n;i++) scanf("%d",a+i);
    	
    	solve();
    	
    	printf("%d
    ",ans);
    	return 0;
    }
    

      

  • 相关阅读:
    JVM类加载的过程
    接口文档设计
    代码规范及CodeReview要点
    Linux权限
    Linux文件
    UltraEdit编辑器基础技巧
    Android环境配置
    JDK 环境配置
    xml没有提示解决办法<eclipse>
    mysql事务实例
  • 原文地址:https://www.cnblogs.com/JYYHH/p/9536686.html
Copyright © 2020-2023  润新知