/* 题目的大意是 给你 N 学生 然后 给前 K个学生编号了 给定的 号码 , 然后你按照 使得接下来学生 学号尽量小的 方法 从第 K+1个学生开始编号 每个号码 自然只能用一次, 解答 : 先将编好的号码排好序,排完后 记录他们之间的 空格数,进行二分查找 有三种情况 1、学生就在 1至K中 2、学生在 K+1 到 D(K个学生中编号最大的那个数) 3、学生在D以后 1、3 都很好求, 对于第二种计算 他距离 第K个 学生都少位 ,然后再 之前算好的空格中 安排他 我为何如此的弱 想了 一天才明白是这样做的 之前的 想法还 wa了 很多次 我为何如此的弱 */ #include <iostream> #include <cstdio> #include<string.h> #include<algorithm> using namespace std; const int maxn=50005; int N[maxn],V[maxn],G[maxn]; int n,K,Q; int bird(int D){ int L=0,R=K,mid; while(L<R){ mid=L+(R-L)/2; if(G[mid]>=D) R=mid; else L=mid+1; } if(G[L]>=D)L--; int Val=D-G[L]+V[L]; return Val; } int main() { V[0]=0; int t; scanf("%d",&t); for(int KA=1;KA<=t;KA++){ printf("Case %d: ",KA); scanf("%d%d%d",&n,&K,&Q); for(int i=1;i<=K;i++){ scanf("%d",&N[i]); V[i]=N[i]; } sort(V+1,V+(K+1)); G[K]=0; for(int i=1;i<=K;i++) G[i]=V[i]-V[i-1]-1+G[i-1]; while(Q--){ int D; scanf("%d",&D); if(D<=K){ printf("%d ",N[D]);continue;} if(D>V[K]){ printf("%d ",D);continue;} D=bird(D-K); printf("%d ",D); } } return 0; }