奇奇怪怪的随机二分

P2249 【深基13.例1】查找

zzy0618 @ 2023-02-10 22:09:56

用随机数取中间值

AC记录

#include<bits/stdc++.h>
using namespace std;
int n,m,q,a[1000005];
int find(int x){
    int l=1,r=n;
    while(l<r){
        int mid=rand()%(r-l+1)+l;
        if (a[mid]>=x)r=mid;
        else l=mid+1;
    }
    if(a[l]==x) return l;
    else return -1;
}
int main(){
    srand((int)time(0));
    scanf("%d%d",&n,&m);
    for(int i=1;i<=n;i++)scanf("%d",&a[i]);
    for(int i=1;i<=m;i++){
        scanf("%d",&q);
        int ans=find(q);
        printf("%d ",ans);
    }
    return 0;
}

by Querainy @ 2023-02-11 07:31:44

使用一个经典的 trick。设答案位于 p。不妨只考虑左端点的收缩。考虑对于一个位置 p-k+1,它被选择作为中点一次的概率,也就是右侧没有一个点比它先被选到的概率,也就是 \frac{1}{k}。所以总和是调和数的 O(\log n)


by fdewc @ 2023-03-04 12:45:30

这跟题解好像


上一页 |