題意:
給你一個序列的遞推函數,m次詢問,詢問這個序列上第bi小的數。
官方題解:
最關鍵的部分在於瞭解STL裏的nth_element函數,簡單介紹一下:
這個函數的時間複雜度近似線性
函數的調用(取第n小):nth_element ( arr.begin() , arr+n,arr.end() )
調用函數後保證比第n個數小的數都在前面,比它大的數在後面
代碼:
#include<bits/stdc++.h>
using namespace std;
int id[105],A[105];
unsigned s[10000005];
unsigned ans[105];
int n,m;
unsigned x,y,z;
unsigned oper(){
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 a,int b){
return A[a] < A[b];
}
int main()
{
int cas = 0;
while(scanf("%d%d%u%u%u",&n,&m,&x,&y,&z)==5){
for(int i=0;i<m;i++){
id[i] = i;
scanf("%d",&A[i]);
}A[m]=n;id[m]=m;
for(int i=0;i<n;i++)s[i] = oper();
sort(id,id+m,cmp);
for(int now,i=m-1,last=A[id[m]];i>=0;i--,last=now){
now = A[id[i]];
if(now==last){
ans[id[i]] = ans[id[i+1]];
}else {
nth_element(s,s+now,s+last);
ans[id[i]] = s[now];
}
}printf("Case #%d:",++cas);
for(int i=0;i<m;i++){
printf(" %u",ans[i]);
}printf("\n");
}return 0;
}