Description
Given a series of n numbers and q queries width w, find the total number of different numbers of all consecutive w numbers for
each query.For example: the numbers are {2, 2, 1, 3, 4, 4, 5} and w is 3. All the consecutive w numbers are:
{2, 2, 1}, 2 different numbers 2 and 1;
{2, 1, 3}, 3 different numbers 2, 1 and 3;
{1, 3, 4}, 3 different numbers …
{3, 4, 4}, 2 different numbers …
{4, 4, 5}, 2 different numbers …The answer is 2 + 3 + 3 + 2 + 2 == 12.
Input
There are no more than 20 test cases. Each case contains three lines.
The first line has two integer numbers n and q.
The second line are n integer numbers.
1 <= n <= 10^ 4 and all the n integer numbers are in range [1, 10^4].The third line are q integer numbers denote each w.
1 <= q <= 10^4, 1 <= w <= n.
Output
For each case, output q lines, the answer for each query.
Sample Input
7 3
2 2 1 3 4 4 5
2 3 7Sample Output
10
12
5Hint
/*
先考虑一个递推关系:当知道宽度为 w - 1 时的答案,每个 w - 1 宽的区间紧挨着之后的那个数,什么情况下是新增的不相同的数?是当这个数上次出现的距离大于w时。
O(n)统计相距任何数相邻两次出现距离为 d 的次数,d为 1, 2, 3, … n
O(n)基于刚刚的统计得到相邻两次出现距离 d 以上的次数。 sumDis[d] 表示同一个数相邻两次出现距离在 d 以上的情况发生的次数。
从宽度 1 开始递推宽度为 w 的答案dp[w],dp[w] = dp[w - 1] + sumDis[w] - sumPostfix,sumPostfix 为 w - 1 长度的后缀中不相同的数的个数,也由递推得到,减去它是因为递推时当宽度加1,总的段数是少1的,就是末尾的那一段 w - 1的区间的统计量要去掉。
*/
#include<stdio.h>
#include<string.h>
#include<stdlib.h>
const int maxn = 1e4 + 10;
int n, q, w;
int a[maxn];
int dp[maxn];
int last[maxn], sumDis[maxn], sumPostfix;
int main()
{
while(scanf("%d%d", &n, &q) != EOF)
{
memset(last, -1, sizeof(last));
memset(sumDis, 0, sizeof(sumDis));
dp[1] = n;
sumPostfix = 0;
for(int i = 0; i < n; i ++)
{
scanf("%d", &a[i]);
sumDis[i - last[a[i]]] ++;
last[a[i]] = i;
}
for(int i = n - 1; i; i --)
sumDis[i] += sumDis[i + 1];
for(int i = 2; i <= n; i ++)
{
sumPostfix += last[a[n - i + 1]] == n - i + 1;
dp[i] = dp[i - 1] + sumDis[i] - sumPostfix;
}
while(q --)
{
scanf("%d", &w);
printf("%d\n", dp[w]);
}
}
return 0;
}
#include <bits/stdc++.h>
using namespace std;
int a[10005], last[10005], d[10005], f[10005];
signed main()
{
ios::sync_with_stdio(false); //取消cin与stdin的同步,提高cin的输入效率
int n, q;
while (cin >> n >> q)
{
memset(last, -1, sizeof(last));
memset(d, 0, sizeof(d));
memset(f, 0, sizeof(f));
for (int i = 0; i < n; i++)
{
cin >> a[i];
d[i - last[a[i]]]++;
last[a[i]] = i;
}
for (int i = n - 1; i >= 1; i--)
{
d[i] += d[i + 1];
}
f[1] = n;
int sumPost = 0;
for (int i = 2; i <= n; i++)
{
sumPost += (last[a[n - i + 1]] == n - i + 1);
f[i] = f[i - 1] + d[i] - sumPost;
}
while (q--)
{
int w;
cin >> w;
printf("%lld\n", f[w]);
}
}
return 0;
}