Uva-1513-Movie collection

最开始在数的前面预留m个位置,然后每次更新的时候把对应书的位置置0,然后将新的位置记录,并在更新为1。其实就是模拟栈的过程,只不过是在前面不断填数而已。

代码:

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
const int maxn=1e5+10;
const int maxm=maxn*2;
int s,n,m,a[maxn],ind[maxn],t[maxm];
int lowbit(int x)
{
    return x&(-x);
}
void Update(int x,int val)
{
    for(;x<=s;t[x]+=val,x+=lowbit(x));
}
int Sum(int x)
{
    int ans=0;
    for(;x>0;ans+=t[x],x-=lowbit(x));
    return ans;
}
int main()
{
    int T;
    scanf("%d",&T);
    while(T--)
    {
        memset(t,0,sizeof(t));
        scanf("%d%d",&n,&m);
        s=n+m;
        for(int i=1;i<=m;i++)
            scanf("%d",&a[i]);
        for(int i=1;i<=n;i++)
        {
            ind[i]=m+i;
            Update(m+i,1);
        }
        bool isfir=true;
        for(int i=1;i<=m;i++)
        {
            if(isfir)
            {
                printf("%d",Sum(ind[a[i]]-1));
                isfir=false;
            }
            else
                printf(" %d",Sum(ind[a[i]]-1));
            Update(ind[a[i]],-1);
            ind[a[i]]=m-i+1;
            Update(ind[a[i]],1);
        }
        printf("\n");
    }
    return 0;
}


你可能感兴趣的:(树状数组)