zoukankan      html  css  js  c++  java
  • [APIO2016]Gap

    题目:UOJ#206。

    题目大意:由于过于冗长,不好解释,所以详见原题。

    解题思路:这是一道交互题。

    对于第一问,很容易解决。由于数列严格递增,所以不会出现相等的情况。

    首先调用MinMax(0,10^18,&l,&r)求出最小值和最大值,然后每次调用MinMax(l+1,r-1,&l,&r)求出次大值、次小值,第三大值、第三小值……

    如此调用$lfloor frac{N+1}{2} floor$次,就可以求出整个数组。然后求值即可。

    对于第二问,首先仍然是求出最小值min和最大值max。

    然后,可以知道[min,max]之间还有N-2个数,那么中间就被分为了N-1份。

    根据抽屉原理可知,两数之间的最大间隔至少为$lceil frac{a_N - a_1}{N-1} ceil$,设其为p。

    那么我们就将查找区间分为N-1份,每次查找的区间大小都为p(最后一个区间除外),然后每次用当前查询到的最小值减去上次查询到的最大值(跳过-1),得出的答案进行比较,最大的那个就是答案。

    由于最大间隔至少为p,所以最大间隔一定在两个不同区间中,因此这样做能得到正确的答案。

    m的值:第一次调用N+1,之后N-1次调用,总共包含不超过N个点,所以$mleq N+1+N+N-1$,即$mleq 3N$,符合条件。

    然后即可AC。

    C++ Code:

    #include"gap.h"
    #define ll long long
    ll p[100005];
    ll findGap(int T,int N){
    	if(T==1){
    		int l=1,r=N;
    		ll LL=0,RR=1000000000000000000;
    		while(l<=r){
    			ll xx,yy;
    			MinMax(LL,RR,&xx,&yy);
    			p[l++]=xx,p[r--]=yy;
    			LL=xx+1,RR=yy-1;
    		}
    		ll max=0;
    		for(int i=1;i<N;++i)
    		if(p[i+1]-p[i]>max)max=p[i+1]-p[i];
    		return max;
    	}else{
    		ll xx,yy;
    		MinMax(0,1000000000000000000,&xx,&yy);
    		ll k=(yy-xx)/(N-1);
    		if((yy-xx)%(N-1))++k;
    		ll prer=xx,max=0,nowl,nowr;
    		for(ll l=xx+1;l<yy;l+=k){
    			ll r=l+k-1;
    			if(r>yy)r=yy-1;
    			MinMax(l,r,&nowl,&nowr);
    			if(nowl-prer>max)max=nowl-prer;
    			if(nowr!=-1)
    			prer=nowr;
    		}
    		if(yy-prer>max)max=yy-prer;
    		return max;
    	}
    }
    
  • 相关阅读:
    51,智联,猎聘,boss 15
    ubuntu重命名[桌面]为[desktop]
    13周让你爱上跑步-计划表
    Typecho的安装 --【Typecho01】.md
    ubuntu跑vue报错:#Error from chokidar # Error: ENOSPC: System limit for number of file watchers reached
    Java中多线程编程--synchronized关键字
    Java中几种常见的设计模式--代理设计模式
    Metaspolit下UAC提权以及日志清除
    JVM初探(五):类的实例化
    JVM初探(四):类加载器
  • 原文地址:https://www.cnblogs.com/Mrsrz/p/8150419.html
Copyright © 2011-2022 走看看