1. 程式人生 > >HDU 6040 Hints of sd0061(nth_element)

HDU 6040 Hints of sd0061(nth_element)

cnblogs blank bsp show pid main 數字 end std

【題目鏈接】 http://acm.hdu.edu.cn/showproblem.php?pid=6040

【題目大意】

  給出一個隨機數生成器,有m個詢問,問第bi小的元素是啥
  詢問中對於bi<bk,bj<bk,有bi+bj<=bk

【題解】

  我們將所有的詢問排序,我們發現倒著處理詢問的時候詢問區間大小下降非常快,
  nth_element(start,start+k,end) 可以近似O(n)查詢區間中第k小的數字,
  並且在處理後保證比第k小小的數字均在其前面(雖然不一定有序),
  所以我們直接倒著處理調用nth_element即可。

【代碼】

#include <cstdio>
#include <algorithm>
using namespace std;
int T,n,m,id[110],b[110];
unsigned s[10000010],a[110],x,y,z;
unsigned xorshf96(){
    unsigned t;
    x^=x<<16;
    x^=x>>5;
    x^=x<<1;
    t=x; x=y; y=z;
    z=t^x^y;
    return z;
}
bool cmp(int x,int y){return b[x]<b[y];}
int main(){
    int Cas=1;
    while(~scanf("%d%d%u%u%u",&n,&m,&x,&y,&z)){
        for(int i=0;i<m;i++){id[i]=i;scanf("%d",&b[i]);}
        for(int i=0;i<n;i++)s[i]=xorshf96();
        sort(id,id+m,cmp);
        b[id[m]=m]=n;
        for(int i=m-1;~i;i--){
            if(b[id[i]]==b[id[i+1]]){
                a[id[i]]=a[id[i+1]];
                continue;
            }
            nth_element(s,s+b[id[i]],s+b[id[i+1]]);
            a[id[i]]=s[b[id[i]]];
        }printf("Case #%d: ",Cas++);
        for(int i=0;i<m-1;i++)printf("%u ",a[i]);
        printf("%u\n",a[m-1]);
    }return 0;
}

HDU 6040 Hints of sd0061(nth_element)