- 询问区间[l,r]内宝石的最大价值,和最大价值的宝石有多少个
- 在最大值上新添加一个属性区间最大值相同的个数cnt,建树的时候初始化cnt = 1(自身:区间[x,x],cnt为1)
tr[u].cnt = 0;
if(tr[u].v == tr[u << 1].v) tr[u].cnt += tr[u << 1].cnt;
if(tr[u].v == tr[u << 1 | 1].v) tr[u].cnt += tr[u << 1 | 1].cnt;
代码如下:
#include<bits/stdc++.h>
using namespace std;
#define mm(a,x) memset(a,x,sizeof a)
#define mk make_pair
#define ll long long
#define pii pair<int,int>
#define inf 0x3f3f3f3f
#define lowbit(x) (x) & (-x)
const int N = 2e5 + 10;
int n,m;
int a[N];
struct Node{
int l,r;
int v,cnt;
}tr[N * 4];
int maxv,cnt;
void pushup(int u){
tr[u].v = max(tr[u << 1].v,tr[u << 1 | 1].v);
tr[u].cnt = 0;
if(tr[u].v == tr[u << 1].v) tr[u].cnt += tr[u << 1].cnt;
if(tr[u].v == tr[u << 1 | 1].v) tr[u].cnt += tr[u << 1 | 1].cnt;
}
void build(int u,int l,int r){
if(l == r) tr[u] = {l,r,a[l],1};
else{
tr[u] = {l,r};
int mid = l + r >> 1;
build(u << 1,l,mid);
build(u << 1 | 1,mid + 1,r);
pushup(u);
}
}
void query(int u,int l,int r){
if(tr[u].l >= l && tr[u].r <= r){
if(maxv == tr[u].v) cnt += tr[u].cnt;
if(maxv < tr[u].v){
maxv = tr[u].v;
cnt = tr[u].cnt;
}
return ;
}
int mid = (tr[u].l + tr[u].r) >> 1;
if(l <= mid) query(u << 1,l,r);
if(r > mid) query(u << 1 | 1,l,r);
}
void modify(int u,int x,int v){
if(tr[u].l == x && tr[u].r == x){
tr[u].cnt = 1;
tr[u].v = v;
}
else{
int mid = (tr[u].l + tr[u].r) >> 1;
if(x <= mid) modify(u << 1,x,v);
else modify(u << 1 | 1,x,v);
pushup(u);
}
}
int main() {
cin >> n >> m;
for(int i = 1; i <= n; i ++ ) cin >> a[i];
build(1,1,n);
string op;
int x,y;
while(m -- ){
cin >> op;
scanf("%d%d",&x,&y);
if(op == "Ask"){
maxv = 0,cnt = 0;
query(1,x,y);
cout<<maxv<<" "<<cnt<<endl;
}else{
modify(1,x,y);
}
}
return 0;
}