列表

详情


NC214396. MakeRounddogVeryHappy

描述

The task is adapted from HDOJ 6701 - Make Rounddog Happy.
Bobo has a sequence of integers a1, a2, ... , an and an integer m.
Let f(j) be the number of i where 1 ≤ i ≤ j and max{ai, ... , aj} - (j - i + 1) ≥ m hold. Find the value of f(1), ... , f(n).

输入描述

The input consists of several test cases terminated by end-of-file.
The first line of each test case contains two integers n and m, and the second line contains n integers a1, a2, ... , an.
 · 1 ≤ n ≤ 106
 · -n ≤ m ≤ n
 · 1 ≤ ai ≤ n
 · The sum of n does not exceed 5×106

输出描述

For each test case, print n integers f(1), ... , f(n).

示例1

输入:

3 0
1 3 2
3 1
1 3 2
5 2
1 2 3 4 5

输出:

1 2 3
0 2 2
0 0 1 2 3

原站题解

上次编辑到这里,代码来自缓存 点击恢复默认模板

C++(g++ 7.5.0) 解法, 执行用时: 1517ms, 内存消耗: 125132K, 提交时间: 2023-07-24 20:30:58

#include <iostream>
#include <cstring>

using namespace std;
using i64 = long long;

const int N = 1000010;

int n, m;
int w[N], f[N][21];
int a[N], b[N];

int maxp(int a, int b) {
  return w[a] > w[b] ? a : b;
}

void init() {
  for (int j = 0; j <= __lg(n); j++)
    for (int i = 1; i + (1 << j) - 1 <= n; i++)
      if (!j) f[i][j] = i;
      else f[i][j] = maxp(f[i][j - 1], f[i + (1 << j - 1)][j - 1]);
}

int ask(int l, int r) {
  int k = __lg(r - l + 1);
  return maxp(f[l][k], f[r - (1 << k) + 1][k]);
}

int main() {
  cin.tie(0)->sync_with_stdio(false);
  while (cin >> n >> m) {
    for (int i = 1; i <= n; i++) {
      a[i] = b[i] = 0;
      cin >> w[i];
    }
    init();
    auto solve = [&](auto self, int l, int r) -> void {
      if (l > r) return;
      int mid = ask(l, r), val = w[mid];
      if (r - mid > mid - l) {
        for (int i = mid; i >= l; i--) {
          int lower = mid, upper = min(r, i + val - m - 1);
          if (lower <= upper) b[lower]++, b[upper + 1]--;
        }
      } else {
        for (int i = mid; i <= r; i++) {
          int lower = max(l, i + 1 + m - val), upper = mid;
          a[i] += max(0, upper - lower + 1); 
        }
      } 
      self(self, l, mid - 1), self(self, mid + 1, r); 
    };
    solve(solve, 1, n);
    for (int i = 1; i <= n; i++) b[i] += b[i - 1];
    for (int i = 1; i <= n; i++) {
      cout << a[i] + b[i] << " \n"[i == n];
    }
  }
  return 0;
}

C++ 解法, 执行用时: 1108ms, 内存消耗: 62004K, 提交时间: 2021-05-20 14:05:42

#include<bits/stdc++.h>
using namespace std;
#define ll long long
int a[1000015];
int stk[1000015];
int L[1000015];
int R[1000015];
ll cf[1000015];
void clear(int n){
	for (int i = 0; i <= n + 5; i++){
		cf[i] = 0;
		L[i] = 0;
		R[i] = 0;
		stk[i] = 0;
		a[i] = 0;
	}
}
int main(){
	int n, m;
	while (cin >> n >> m){
		int top = 0;
		clear(n);
		for (int i = 1; i <= n; i++){
			scanf("%d", &a[i]);
		}
		for (int i = 1; i <= n; i++){
			while (top>0 && a[i] >= a[stk[top]]){
				top--;
			}
			L[i] = stk[top]+1;
			stk[++top] = i;
		}
		top = 0;	
		for (int i = 1; i <= n + 5; i++)stk[i] = 0;
		stk[0] = n+1;
		for (int i = n; i >= 1; i--){
			while (top>0 && a[i] > a[stk[top]]){
				top--;
			}
			R[i] = stk[top]-1;
			stk[++top] = i;
		}
		int p;
		ll res = 0;
		int Max;
		for (int i = 1; i <= n; i++){
			p = a[i] - m;
			int l = i;
				for (int j = L[i]; j <= i; j++){
					int r = min(j + p-1,R[i]);
					if (l>r)continue;
					cf[l] += 1; cf[r + 1] -= 1;
				}
	
		}
		for (int i = 1; i <= n; i++){
			cf[i] = cf[i - 1] + cf[i];
			printf("%lld ",cf[i]);
		}
		printf("\n");
	}
}

上一题