每k个删掉一个,删掉之后对新序列继续这样的操作
多次查询,求第m次是删掉了哪个位置的元素
对于每个元素的下标是0~n-1(方便计算,1~n也可以),如果某个元素坐标 i 模 k 等于0则是现在要删掉的,否则会保留到下一轮,而到下一轮,新的位置是i-i/k-1
而其实对于每一轮删的操作都是一样的,是不是也可以转化为,当前轮为i-i/k-1位置的元素删掉的轮次加一
利用这个性质,就可以很好的O(n)递推了
#include<bits/stdc++.h>
using namespace std;
struct node
{
int x,y,index;//x是删掉的轮次,y是当前轮次第几个删
bool operator < (const node & a)const
{
if(x==a.x)
return y<a.y;
return x<a.x;
}
}num[3000005];
int main()
{
int T,i,n,k,q;
cin>>T;
while(T--)
{
cin>>n>>k>>q;
int l=0;
for(i=0;i<n;i++)
{
if(i%k)
num[i].x=num[i-i/k-1].x+1,num[i].y=num[i-i/k-1].y;
else
num[i].x=1,num[i].y=l++;
num[i].index=i+1;
}
sort(num,num+n);
while(q--)
{
scanf("%d",&i);
printf("%d\n",num[i-1].index);
}
}
return 0;
}