考虑给每个编号开一个版本,维护区间和,于是想到主席树,N<=1e5 ,离散化即可
注意把操作离线下来的编码也要离散化
#include <bits/stdc++.h>
#define INF (1ll<<60)
#define eps 1e-6
using namespace std;
typedef long long ll;
typedef long long LL;
typedef pair<int, int> pii;
typedef vector<int> vi;
typedef unsigned long long ull;
typedef vector<vector<int> > vii;
typedef vector<vector<vector<int> > > viii;
typedef vector<ll> vl;
typedef vector<vector<ll> > vll;
typedef vector<double> vd;
typedef vector<vector<double> > vdd;
#define time mt19937_64 rnd(chrono::steady_clock::now().time_since_epoch().count());//稳定随机卡牛魔 ull
const int N=1e5+9;
int a[N];
vi X;
int binary(int x){
return lower_bound(X.begin(),X.end(),x)-X.begin()+1;
}
struct Q{
char op;
int l,r,k;
}que[N];
//可持久化线段树
struct KCJSEG{
struct node{
int l,r;
ll val;
}seg[N<<5];
#define tl(id) seg[id].l
#define tr(id) seg[id].r
#define pushup(id) seg[id].val=seg[tl(id)].val+seg[tr(id)].val
int root[N],index,mx;
int inrange(int L,int R,int l,int r){return L>=l && R<=r;}
int outofrange(int L,int R,int l,int r){return L>r || l>R;}
void update(int post,int &curr,int l,int r,int pos,int v){
curr=++index;
seg[curr]=seg[post];
if(l==r){
seg[curr].val+=v;
return;
}
int mid=(l+r)>>1;
if(mid>=pos){
update(tl(post),tl(curr),l,mid,pos,v);
}else{
update(tr(post),tr(curr),mid+1,r,pos,v);
}
pushup(curr);
}
void insert(int &id,int l,int r,int pos,int k){
if(!id){
id=++index;
}
if(l==r){
seg[id].val+=k;
return;
}
int mid=(l+r)>>1;
if(mid>=pos){
insert(tl(id),l,mid,pos,k);
}else{
insert(tr(id),mid+1,r,pos,k);
}
pushup(id);
}
ll query(int curr,int L,int R,int l,int r){
if(inrange(L,R,l,r)){
return seg[curr].val;
}else if(!outofrange(L,R,l,r)){
int mid=(L+R)>>1;
return query(tl(curr),L,mid,l,r)+query(tr(curr),mid+1,R,l,r);
}else{
return 0;
}
}
}t;
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr), cout.tie(nullptr);
int n,m;
cin>>n>>m;
for(int i=1;i<=n;i++){
cin>>a[i];
}
for(int i=1;i<=n;i++){
X.push_back(a[i]);
}
for(int i=1;i<=m;i++){
char op;
cin>>op;
if(op=='C'){
int a,p;
cin>>a>>p;
que[i]={'C',a,a,p};
X.push_back(p);
}else{
int l,r,k;
cin>>l>>r>>k;
que[i]={'Q',l,r,k};
X.push_back(k);
}
}
sort(X.begin(), X.end());
X.erase(unique(X.begin(),X.end()),X.end());
for(int i=1;i<=n;i++){
a[i]= binary(a[i]);
t.insert(t.root[a[i]],1,n,i,1);
}
for(int i=1;i<=m;i++){
if(que[i].op=='C'){
int pos=que[i].l;
int p=que[i].k;
p= binary(p);
t.insert(t.root[a[pos]],1,n,pos,-1);
a[pos]=p;
t.insert(t.root[a[pos]],1,n,pos,1);
}else{
int id=que[i].k;
id=binary(id);
int l=que[i].l;
int r=que[i].r;
cout<<t.query(t.root[id],1,n,l,r)<<'\n';
}
}
return 0;
}