思路:
已知dp[n],则dp[n+1]等于dp[n]减去最后一组长度为n的不同数的个数,因为这一组不能再加一个数使长度变成n+1
然后对于长度为n的每组加上后一个数,如果这个数在前面长度为n的串中没有出现则dp[n+1]加1
#include<cstdio>
#include<cstring>
typedef long long ll;
const int maxn=1000007;
ll dp[maxn];
int d[maxn]; //第i个数和前面最近相同的数的距离 例如1,2,1 d[3]=2
int r[maxn]; //和前面最近相同的数的距离为i的个数
int tmp[maxn];
int lastp[maxn]; //数i的最近上一个位置
int x[maxn];
int df[maxn]; //从n-i+1到n不同的数的个数
int main()
{
int n,q;
while(~scanf("%d",&n),n)
{
int i;
memset(lastp,0,sizeof(lastp));
for(i=1;i<=n;i++)
{
scanf("%d",x+i);
d[i] = i-lastp[x[i]];
lastp[x[i]] = i;
}
memset(r,0,sizeof(r));
for(i=1;i<=n;i++)
{
r[d[i]]++;
}
memset(tmp,0,sizeof(tmp));
int t=0;
for(i=n;i>0;i--)
{
if(!tmp[x[i]])
{
tmp[x[i]]=1;
t++;
}
df[n-i+1]=t;
}
dp[1]=n;
int sum=n;
for(i=2;i<=n;i++)
{
dp[i] = dp[i-1] - df[i-1];
sum -= r[i-1];
dp[i] += sum;
}
scanf("%d",&q);
while(q--)
{
scanf("%d",&t);
printf("%I64d\n",dp[t]);
}
}
return 0;
}