LOJ#2569. 「APIO2016」最大差分 分块+交互

比较有趣的交互题.    

subtask1:    

由于每次调用这个函数可以返回值域中的最大值和最小值,所以可以每次查询出两个元素.   

那么每次查到 $x,y$ 后就将查询区间缩小为 $[x+1,y-1]$,这样可以在规定操作次数内解决问题.   

subtask2:   

这个 subtask 比较困难.  

首先,我们发现答案的下界是 $B=\frac{Max-Min}{n-1}$,那么所有在 $B$ 长度内的两个数都不会产生贡献.  

考虑将 $[Min,Max]$ 的值域分成 $m$ 块,每块的长度为 $B$,那么有贡献的两个数一定是一个块的最大值和下一块的最小值.             

查询总代价为: $n+1+n-1+n \leqslant 3n$.                         

code:   

#include "gap.h"
#include  
#include  
#include      
#include  
#define pb push_back
#define ll long long      
using namespace std;
const ll inf=1000000000000000002ll;
vectora; 
void MinMax(ll l,ll r,ll &x,ll &y) {  
	printf("? %lld %lld\n",l,r);    
	fflush(stdout);    
	scanf("%lld%lld",&x,&y);    
	fflush(stdin);  
}
ll sol1(int len) {  
	ll l=-inf,r=inf;  
	int tot=0;  
	while(l<=r) {                
		ll mi,ma;   
		MinMax(l,r,mi,ma);      
		if(mi>=0) a.pb(mi),++tot;  
		if(ma>mi) a.pb(ma),++tot; 
		l=mi+1,r=ma-1;     
		if(tot==len) break; 
	}
	sort(a.begin(),a.end());  
	ll ans=0;  
	for(int i=1;i 
   

  

 

你可能感兴趣的:(LOJ#2569. 「APIO2016」最大差分 分块+交互)