#define _USE_MATH_DEFINES #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include #include using namespace std; #define trace(...) __f(#__VA_ARGS__, __VA_ARGS__) template void __f(const char* name, Arg1&& arg1){ cerr << name << ": " << arg1 << endl; } template void __f(const char* names, Arg1&& arg1, Args&&... args){ const char* comma = strchr(names + 1, ','); cerr.write(names, comma - names) << ": " << arg1 << " |"; __f(comma + 1, args...); } typedef long long int64; typedef pair ii; const int INF = 1 << 29; const int MOD = 1e9 + 7; const int N = 1e5 + 10; ii a[N]; int L[N], R[N], f[N]; int dor[20][N], dand[20][N], dmin[20][N], dmax[20][N]; int lg2[N]; bool visit[N]; int find(int x) { if (f[x] != f[f[x]]) f[x] = find(f[x]); return f[x]; } int get_or(int x, int y) { int k = lg2[y - x + 1]; return dor[k][x] | dor[k][y - (1 << k) + 1]; } int get_and(int x, int y) { int k = lg2[y - x + 1]; return dand[k][x] & dand[k][y - (1 << k) + 1]; } int get_min(int x, int y) { int k = lg2[y - x + 1]; return min(dmin[k][x], dmin[k][y - (1 << k) + 1]); } int get_max(int x, int y) { int k = lg2[y - x + 1]; return max(dmax[k][x], dmax[k][y - (1 << k) + 1]); } struct Node { int a, b; Node *left, *right; int val; void update(int C) { val = max(val, C); } void pushdown() { left->update(val); right->update(val); } }; Node pool[N << 1], *last; Node* build(int a, int b) { Node* cur = last++; cur->a = a; cur->b = b; cur->val = -1; if (a + 1 == b) return cur; cur->left = build(a, (a + b) / 2); cur->right = build((a + b) / 2, b); return cur; } int A, B, C; void insert(Node* cur) { if (cur->a >= A && cur->b <= B) { cur->update(C); return; } cur->pushdown(); if ((cur->a + cur->b) / 2 > A) insert(cur->left); if ((cur->a + cur->b) / 2 < B) insert(cur->right); } int query(Node* cur) { if (cur->a + 1 == cur->b) { return cur->val; } cur->pushdown(); if ((cur->a + cur->b) / 2 > A) return query(cur->left); return query(cur->right); } int main() { lg2[1] = 0; for (int i = 2; i < N; ++i) lg2[i] = lg2[i / 2] + 1; int n, m; scanf("%d%d", &n, &m); for (int i = 0; i < n; ++i) { scanf("%d", &a[i].first); a[i].second = i; } for (int i = 0; i < n; ++i) { dand[0][i] = dor[0][i] = a[i].first; dmin[0][i] = dmax[0][i] = a[i].first; } for (int k = 1; k < 20; ++k) { for (int i = 0; i + (1 << k) <= n; ++i) { dand[k][i] = dand[k - 1][i] & dand[k - 1][i + (1 << (k - 1))]; dor[k][i] = dor[k - 1][i] | dor[k - 1][i + (1 << (k - 1))]; dmin[k][i] = min(dmin[k - 1][i], dmin[k - 1][i + (1 << (k - 1))]); dmax[k][i] = max(dmax[k - 1][i], dmax[k - 1][i + (1 << (k - 1))]); } } sort(a, a + n); last = pool; Node* root = build(0, n); // for (int i = 0; i < n; ++i) { // for (int j = i; j < n; ++j) { // int64 cur_or = get_or(i, j); // int64 cur_and = get_and(i, j); // int64 cur_min = get_min(i, j); // int64 cur_max = get_max(i, j); // if ((cur_or - cur_and) - (cur_max - cur_min) >= m) { // A = i, B = j + 1; // C = j - i + 1; // insert(root); // } // } // } for (int i = 0; i < n; ++i) f[i] = L[i] = R[i] = i; for (int i = 0; i < n; ++i) { int j = a[i].second; // trace(i, a[i].first, j); if (j - 1 >= 0 && visit[j - 1]) { int k = j - 1, rk = find(k), rj = find(j); L[rk] = min(L[rk], L[rj]); R[rk] = max(R[rk], R[rj]); f[rj] = rk; } if (j + 1 < n && visit[j + 1]) { int k = j + 1, rk = find(k), rj = find(j); L[rk] = min(L[rk], L[rj]); R[rk] = max(R[rk], R[rj]); f[rj] = rk; } int rj = find(j); int64 cur_or = get_or(L[rj], R[rj]); int64 cur_and = get_and(L[rj], R[rj]); int64 cur_min = get_min(L[rj], R[rj]); // trace(L[rj], R[rj], cur_and, cur_or, cur_min, a[i].first); if ((cur_or - cur_and) - (a[i].first - cur_min) >= m) { // trace("found"); A = L[rj], B = R[rj] + 1; C = R[rj] - L[rj] + 1; insert(root); } visit[j] = true; } // // trace("--"); fill(visit, visit + n, false); for (int i = 0; i < n; ++i) f[i] = L[i] = R[i] = i; for (int i = n - 1; i >= 0; --i) { int j = a[i].second; // trace(i, a[i].first, j); if (j - 1 >= 0 && visit[j - 1]) { int k = j - 1, rk = find(k), rj = find(j); L[rk] = min(L[rk], L[rj]); R[rk] = max(R[rk], R[rj]); f[rj] = rk; } if (j + 1 < n && visit[j + 1]) { int k = j + 1, rk = find(k), rj = find(j); L[rk] = min(L[rk], L[rj]); R[rk] = max(R[rk], R[rj]); f[rj] = rk; } int rj = find(j); int64 cur_or = get_or(L[rj], R[rj]); int64 cur_and = get_and(L[rj], R[rj]); int64 cur_max = get_max(L[rj], R[rj]); // trace(L[rj], R[rj], cur_and, cur_or, cur_max, a[i].first); if ((cur_or - cur_and) - (cur_max - a[i].first) >= m) { // trace("found", R[rj] - L[rj] + 1); A = L[rj], B = R[rj] + 1; C = R[rj] - L[rj] + 1; insert(root); } visit[j] = true; } for (int i = 0; i < n; ++i) { A = i; printf("%d\n", query(root)); } return 0; }