description:
n个数 有两种操作 1. 将a[x]的值改成y 2.查询区间l,r中的最大值 以及 最大值出现的次数
solution:
线段树维护最大值的同时,再维护一个出现次数。
对于出现次数的修改需要注意:
1.初始值为1 2.更新操作时 当结点值改变 出现次数变成 -> 只有当父节点最大值 等于左儿子或者右儿子的最大值时 才能加上次数
3.查询时所有与最大值相同区间出现次数都需要相加
code:
#include <bits/stdc++.h> using namespace std; #define LL long long #define lson v << 1 #define rson (v << 1 | 1) const int N = 2e5 + 40; struct node { int l, r; int res, sum; }; node t[N << 2]; int n, m; void push_up(int v) { t[v].res = max(t[lson].res, t[rson].res); t[v].sum = 0; if (t[v].res == t[lson].res) t[v].sum += t[lson].sum; if (t[v].res == t[rson].res) t[v].sum += t[rson].sum; } void build(int v, int l, int r) { t[v].l = l, t[v].r = r; if (l == r) { scanf("%d", &t[v].res); t[v].sum = 1; return; } int mid = l + r >> 1; build(lson, l, mid); build(rson, mid + 1, r); push_up(v); } void update(int v, int x, int y) { if (t[v].l == t[v].r && t[v].l == x) { t[v].res = y; t[v].sum = 1; return; } int mid = t[v].l + t[v].r >> 1; if (x <= mid) update(lson, x, y); else update(rson, x, y); push_up(v); } node now; void query(int v, int l, int r) { if (t[v].l >= l && t[v].r <= r) { if (t[v].res == now.res) { now.sum += t[v].sum; } if (t[v].res > now.res) { now.res = t[v].res; now.sum = t[v].sum; } return; } int mid = t[v].l + t[v].r >> 1; if (l <= mid) query(lson, l, r); if (r > mid) query(rson, l, r); } int main() { cin >> n >> m; build(1, 1, n); char op[15]; int x, y; while (m--) { scanf("%s%d%d", op, &x, &y); if (op[0] == 'C') { update(1, x, y); } else { now.sum = now.res = 0; query(1, x, y); printf("%d %d\n", now.res, now.sum); } } return 0; }