题目大意:有n个电影碟,要看m次电影(1<=n,m<=100000),初始时从上到下分别是第1个到第n个电影,每次拿出一个电影后,把它放在最上面,求每拿出一个电影,在它上面的电影数是多少。
用数组模拟栈,只不过栈有些元素可能是空的,每次拿出后放在栈顶,并随时更新每个电影对应的在栈中的位置,求在它上面的电影数就是对数组求和。每次拿出把这个位置的值置为0,即减1,在栈顶放入就在栈顶加1,最终求和。
#include<stdio.h>
#include<stdlib.h>
int a[100010];
int b[35];
int c[275000];
int ans[100010];
int n;
int BIT_sum(int x);
void BIT_add(int x,int u);
int main(void)
{
int i,j,u,p,q,pi,qi;
b[1]=1;
for(i=2;i<=30;i++)
{
b[i]=b[i-1]*2+1;
}
scanf("%d",&pi);
for(qi=0;qi<pi;qi++)
{
scanf("%d%d",&p,&q);
j=1;
while(p+q>b[j])
{
j++;
}
n=b[j];
for(i=0;i<=n;i++)
{
c[i]=0;
}
for(i=1;i<=p;i++)
{
BIT_add(i,1);
}
for(i=1;i<=p;i++)
{
a[i]=p+1-i;
}
for(i=1;i<=q;i++)
{
scanf("%d",&u);
ans[i]=p-BIT_sum(a[u]);
BIT_add(a[u],-1);
BIT_add(i+p,1);
a[u]=i+p;
}
printf("%d",ans[1]);
for(i=2;i<=q;i++)
{
printf(" %d",ans[i]);
}
printf("\n");
}
return 0;
}
int BIT_sum(int x)
{
int ret=0;
while(x>0)
{
ret=ret+c[x];
x=x-(x&-x);
}
return ret;
}
void BIT_add(int x,int u)
{
while(x<=n)
{
c[x]=c[x]+u;
x=x+(x&-x);
}
}