Loading

二分

\(Orz\)集训队论文

选数问题:选出集合中第\(i\)小的数
如果排序的话,复杂度是\(nlogn\)的,是因为他对一些没有用的东西也进行了操作,所以我们尽量少进行没有用的操作,有一种\(O(n)\)的算法
内容见\(link\)
复杂度证明:每次都选择一个数后,我们只用向另一半递归,所以计算次数为
\(n+n/2+n/4+n/8+....+1\),易知这是一个收敛的等比数列,和不会大于\(2n\),故复杂度是\(O(n)\)
所以说复杂度不能想当然\(logn\),还是要自己推,一般如果\(check\)函数的计算范围随着端点的缩小而缩小,复杂度就是\(O(n)\)的,如果\(check\)复杂度一直是\(O(n)\),那么就是\(nlogn\)
code

#include <cstdio>
#include <cstring>
#include <algorithm>
#include <ctime>
#define int long
#define R register int
#define printf tz1=printf

using namespace std ;
typedef long long L ;
typedef long double D ;
typedef unsigned G ;
const int N = 5e6 + 10 ;

inline int read(){
	int w = 0 ; bool fg = 0 ; char ch = getchar() ;
	while( ch < '0' || ch > '9' ) fg |= ( ch == '-' ) , ch = getchar() ;
	while( ch >= '0' && ch <= '9' ) w = ( w << 1 ) + ( w << 3 ) + ( ch - '0' ) , ch = getchar() ;
	return fg ? -w : w ;
}

int tz1 , n , m , a [N] ;

void sc(){
	n = read() , m = read() ; m ++ ; 
	for( R i = 1 ; i <= n ; i ++ ) a [i] = read() ; 
}

inline void debug( int l , int r ){
	for( R i = l ; i <= r ; i ++ ) printf( "%ld " , a [i] ) ;  puts( "" ) ;
}

inline void choose( int l , int r , int x ){
//	printf( "L%ld R%ld X%ld\n" , l , r , x ) ;
	int mid = ( l + r ) >> 1 ; //懒得写随机,所以取的中点
	swap( a [mid] , a [l] ) ;
	int cnt = l ; //debug( l , r ) ;
	for( R i = l + 1 ; i <= r ; i ++ )
		if( a [i] < a [l] ) swap( a [++ cnt] , a [i] ) ;
	swap( a [cnt] , a [l] ) ;
	if( cnt - l == x - 1 ) { printf( "%ld\n" , a [cnt] ) ; return ; }
	if( cnt - l <  x ) choose( cnt + 1 , r , x - cnt + l - 1 ) ;  
	else choose( l , cnt , x ) ;
}	

void work(){
	choose( 1 , n , m ) ;
}

signed main(){
	sc() ;
	work() ;
	return 0 ;
}

一种二分答案保证可以去到所有点的写法(\(orz\ zero4338\)赐教)

	int lside = 0 , rside = balabala , ans ;
	while( lside <= rside ){
		mid = ( lside + rside ) >> 1 ;
		if( check() ) ans = mid , rside = mid - 1 ; //这里要看check如何定义缩小左右边界
		else lside = mid + 1 ;
	} printf( "%ld\n" , ans ) ;

其实很多题都可以二分答案,所以见到题看有没有单调性就可以直接想如何写\(check\)
这里放几个二分答案的链接
\(link1\)
\(link2\)
\(link3\)
\(link4\)
\(link5\)

posted @ 2021-05-22 06:41  Soresen  阅读(104)  评论(1)    收藏  举报