链接
https://vjudge.net/problem/UVA-1513
题解
其实没必要连续,我先开一个二倍长的数组把元素放在最后,每次开辟前面新的元素放一个
1
1
1,树状数组快速查询前缀和就好了
注意因为可能
m
>
n
m>n
m>n所以不应该把元素初始存储在
n
+
i
n+i
n+i而应该初始存储在
m
+
i
m+i
m+i
代码
#include <bits/stdc++.h>
#define maxn 200010
#define cl(x) memset(x,0,sizeof(x))
#define lowbit(x) (x&-x)
using namespace std;
typedef long long ll;
ll bit[maxn], N, M, front, pos[maxn];
ll bitsum(ll pos)
{
ll ans(0);
for(;pos;pos-=lowbit(pos))ans+=bit[pos];
return ans;
}
void bitadd(ll pos, ll v)
{
for(;pos<maxn;pos+=lowbit(pos))bit[pos]+=v;
}
ll read(ll x=0)
{
ll c, f=1;
for(c=getchar();!isdigit(c);c=getchar())if(c=='-')f=-f;
for(;isdigit(c);c=getchar())x=x*10+c-48;
return f*x;
}
int main()
{
auto T=read();
while(T--)
{
N=read(), M=read();
cl(bit);
for(auto i=1;i<=N;i++)bitadd(i+100000,1ll), pos[i]=100000+i;
front=100000;
while(M--)
{
auto a=read();
printf("%lld",bitsum(pos[a]-1));
if(M)putchar(32);
else putchar(10);
bitadd(pos[a],-1);
bitadd(front,1);
pos[a]=front--;
}
}
return 0;
}