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;
}