给定一个长度为 � n 的序列 � a,我们通过以下方式构造序列 � b: 初始时 � b 为空序列。 对于 � = 1 , 2 , ⋯ , � i=1,2,⋯,n,我们依次向 � b 的尾部插入 1 , 2 , ⋯ , � � 1,2,⋯,a i 。 dXqwq 定义一个序列的最小众数为所有出现次数最大的数的最小值。例如 [ 1 , 1 , 4 , 5 , 1 , 4 ] [1,1,4,5,1,4] 的最小众数为 1 1,而 [ 1 , 14 , 5 , 14 , 19 , 19 , 8 , 10 ] [1,14,5,14,19,19,8,10] 的最小众数为 14 14。 你需要求出 � b 的每个子区间的最小众数的和。由于答案可能很大,你只需要输出它对 998244353 998244353 取模后的值。 输入格式 第一行输入一个整数 � n。 第二行输入 � n 个整数 � � a i 。 输出格式 输出一个整数,代表 � b 的每个子区间的最小众数的和对 998244353 998244353 取模的值。
时间: 2023-09-28 17:10:02 浏览: 423
这是一个非常有趣的问题!让我们来解决它。
首先,我们可以观察到,序列b中的每个子区间的最小众数等于这个子区间中的最小值。因此,我们需要找到每个子区间的最小值,并将它们相加。
为了解决这个问题,我们可以使用单调栈的方法。我们可以维护一个单调递增的栈,栈中存储的是序列a中元素的下标。
算法如下:
1. 初始化一个空栈stack。
2. 遍历序列a的每个元素a[i]:
- 当栈不为空且a[i]小于等于栈顶元素a[stack.top()]时,不断弹出栈顶元素,并计算以弹出元素为最小值的子区间的个数count。将count乘以a[stack.top()]加到答案result上,并对result取模。
- 将a[i]入栈。
3. 如果栈不为空,重复步骤2中的操作,直到栈为空。
4. 输出答案result对998244353取模后的值。
下面是一个C++的实现示例:
```cpp
#include <iostream>
#include <stack>
using namespace std;
const int MOD = 998244353;
int main() {
int n;
cin >> n;
stack<int> st;
long long result = 0;
for (int i = 0; i < n; i++) {
int ai;
cin >> ai;
while (!st.empty() && ai <= ai[st.top()]) {
int top = st.top();
st.pop();
long long count = (i - (st.empty() ? -1 : st.top())) * ai[top];
result = (result + count) % MOD;
}
st.push(i);
}
while (!st.empty()) {
int top = st.top();
st.pop();
long long count = (n - (st.empty() ? -1 : st.top())) * ai[top];
result = (result + count) % MOD;
}
cout << result << endl;
return 0;
}
```
希望以上解答对您有所帮助!如果您有任何问题,请随时提问。
阅读全文