#include <iostream>
#include <cstdio>
#include <cstring>
#include <cstdlib>
#include <algorithm>
#include <vector>
using namespace std;
typedef long long LL;
#define all(a) (a).begin(), (a).end()
const int maxn = 1e4 + 7;
struct ST {
struct Node {
int a[22];
int &operator [] ( int x) {
return a[x];
}
};
const static int maxn = 1e6 + 7;
vector<Node> dp;
static int index[maxn];
static void init_index() {
index[1] = 0;
for ( int i = 2; i < maxn; i ++) {
index[i] = index[i - 1];
if (!(i & (i - 1))) index[i] ++;
}
}
void init_min(vector< int > &a) {
int n = a.size();
dp.resize(n);
for ( int i = 0; i < n; i ++) dp[i][0] = a[i];
for ( int j = 1; (1 << j) <= n; j ++) {
for ( int i = 0; i + (1 << j) - 1 < n; i ++) {
dp[i][j] = min(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
}
}
}
void init_max(vector< int > &a) {
int n = a.size();
dp.resize(n);
for ( int i = 0; i < n; i ++) dp[i][0] = a[i];
for ( int j = 1; (1 << j) <= n; j ++) {
for ( int i = 0; i + (1 << j) - 1 < n; i ++) {
dp[i][j] = max(dp[i][j - 1], dp[i + (1 << (j - 1))][j - 1]);
}
}
}
int query_min( int L, int R) {
int p = index[R - L + 1];
return min(dp[L][p], dp[R - (1 << p) + 1][p]);
}
int query_max( int L, int R) {
int p = index[R - L + 1];
return max(dp[L][p], dp[R - (1 << p) + 1][p]);
}
};
int ST::index[maxn];
ST st1, st2;
vector< int > a, b;
bool chk[maxn][1000];
int last[maxn];
int main() {
#ifndef ONLINE_JUDGE
freopen ( "in.txt" , "r" , stdin);
#endif // ONLINE_JUDGE
puts ( "Case #1:" );
int n, m;
cin >> n >> m;
a.resize(n);
for ( int i = 0; i < n; i ++) {
scanf ( "%d" , &a[i]);
}
b = a;
ST::init_index();
st1.init_max(a);
st2.init_min(a);
sort(all(a));
a.erase(unique(all(a)), a.end());
for ( int i = 0; i < n; i ++) {
b[i] = lower_bound(all(a), b[i]) - a.begin();
}
for ( int i = 0; i < n; i ++) {
chk[i][1] = true ;
memset (last, 0xff, sizeof (last));
last[b[i]] = i;
for ( int L = 2; i + L - 1 < n && L <= 1000; L ++) {
if (last[b[i + L - 1]] >= i) break ;
last[b[i + L - 1]] = i + L - 1;
chk[i][L] = true ;
}
}
for ( int i = 0; i < m; i ++) {
int k;
scanf ( "%d" , &k);
int ans = 0;
for ( int i = 0; i + k - 1 < n; i ++) {
ans += st1.query_max(i, i + k - 1) - st2.query_min(i, i + k - 1) == k - 1 && chk[i][k];
}
printf ( "%d\n" , ans);
}
return 0;
}
|