题意:你有n个带有编号1到n的盘子叠在一块,编号小的在上面,编号大的在下面,你现在有q个操作,每次操作抽出一个盘子,求这个盘子的上面有几个盘子, 并且把这个盘子放在顶面。
思路:可用树状数组,每次抽出一个盘子,给这个盘子一个新的最大的下标值插入树状数组。
#include<cstdio>
#include<cstring>
using namespace std;
const int maxn=200000+5;
int n,c[maxn],a[maxn],ans[maxn],cnt;
int low(int x)
{
return x&(-x);
}
void add(int k,int value)
{
while(k)
{
c[k]+=value;
k-=low(k);
}
}
void init()
{
cnt=n;
memset(c,0,sizeof(c));
for(int i=1;i<=n;i++)
{
a[i]=n-i+1;
add(a[i],1);
}
}
int sum(int k)
{
int res=0;
while(k<maxn)
{
res+=c[k];
k+=low(k);
}
return res;
}
int main()
{
int T;
scanf("%d",&T);
while(T--)
{
int m,i,k,tot=0;
scanf("%d%d",&n,&m);
init();
while(m--)
{
scanf("%d",&k);
ans[++tot]=sum(a[k])-1;
add(a[k],-1);
a[k]=++cnt;
add(a[k],1);
}
for(i=1;i<tot;i++)
printf("%d ",ans[i]);
printf("%d\n",ans[tot]);
}
}