思路:
参考别人的博客:dp[i]=dp[i-1]-A+B;
减的A是最后一个长度为i-1的区间的不同数的个数,这个很容易预处理得出来。
加的B是第t个数到它上一个数的距离大于i-1的个数.
这个B值也容易得出。
用s[i]表示离上一个数的距离为i的个数,不断减掉就得到B了。
#include<bits/stdc++.h>
using namespace std;
const int maxn = 1e6+7;
#define LL long long
int a[maxn];
int fir[maxn],s[maxn],ss[maxn];
LL dp[maxn];
int main()
{
int n;
while(scanf("%d",&n)!=EOF && n)
{
memset(fir,0,sizeof(fir));
memset(s,0,sizeof(s));
for(int i =1;i<=n;i++)
scanf("%d",&a[i]);
for(int i = 1;i<=n;i++)
{
s[i-fir[a[i]]]++;
fir[a[i]]=i;
}
memset(fir,0,sizeof(fir));
fir[a[n]]=1;
ss[1]=1;
for(int i = 2;i<=n;i++)
{
if(fir[a[n-i+1]]==0)
{
fir[a[n-i+1]]=1;
ss[i]=ss[i-1]+1;
}
else
ss[i]=ss[i-1];
}
dp[1]=n;
int sum = n;
for(int i = 2;i<=n;i++)
{
dp[i]=dp[i-1]-ss[i-1];
sum-=s[i-1];
dp[i]+=sum;
}
int m;
scanf("%d",&m);
while(m--)
{
int q;
scanf("%d",&q);
printf("%lld\n",dp[q]);
}
}
}