1 条题解
-
0
- 分别计算数组中的每一个数 ,能够作为某个子数组的最小值的次数
- 也就是:找到 左边第一个 的数的下标
- 找到 右边第一个 的数的下标
- 那么 之间的数组成的子数组,其最小值都是
#include <bits/stdc++.h> using namespace std; using i64 = long long; const int P = 998244353; int gao(const vector<int>& a) { int n = a.size(); // L(i): 左边第一个 <= a[i] 的数的下标 vector<int> L(n, -1); // R(i): 右边第一个 < a[i] 的数的下标 vector<int> R(n, n); vector<int> s(n); // 用来从左往右放入 a[i] int e = 0; // s 中元素的个数 for (int i = 0; i < n; i++) { // 在 s 里从后往前找到第一个 <= a[i] // 拿出的时候确定右边第一个 < a[s[e - 1]] 的就是 a[i] while (e > 0 && a[s[e - 1]] > a[i]) R[s[--e]] = i; // 放入的时候确定左边第一个 <= a[i] 的 if (e != 0) L[i] = s[e - 1]; s[e++] = i; } i64 ans = 0; for (int i = 0; i < n; i++) { ans = (ans + (i64) (i - L[i]) * (R[i] - i) * a[i]) % P; } return ans; } int main() { ios::sync_with_stdio(false); cin.tie(0); cout.tie(0); int n; cin >> n; vector<int> a(n); for (int i = 0; i < n; i++) cin >> a[i]; cout << gao(a) << '\n'; return 0; }
- 1
信息
- ID
- 162
- 时间
- 100ms
- 内存
- 32MiB
- 难度
- 5
- 标签
- 递交数
- 76
- 已通过
- 28
- 上传者