如果你用的树状数组,并且有这样一行:
for(;x<=n+q;x+=x&(-x))
那么你在输入的时候请不要用 while 循环,因为 q 会持续减一,导致 0 分。
0分 record 如下:
#include<iostream>
using namespace std;
const int N=1e6+10;
#define ll long long
ll n,q,x,a[N];
ll op;
struct node{
ll t[N*2];
void upd(ll x,ll v){
if(x==0)return;
for(;x<=n+q;x+=x&(-x)){
t[x]+=v;
}
}
ll qry(ll x){
if(x==0)return 0;
ll res=0;
for(;x;x-=x&(-x)){
res+=t[x];
}
return res;
}
}t1,t2;
void solve(int x){
t1.upd(a[x],-1);
t1.upd(a[x]+1,1);
t2.upd(a[x]+1,a[x]+1);
t2.upd(a[x],-a[x]);
a[x]++;
}
int main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n>>q;
for(ll i=1;i<=n;i++){
cin>>x;
solve(x);
}
while(q--){
cin>>op>>x;
if(op==1){
solve(x);
}
else if(op==2){
t1.upd(a[x],-1);
t1.upd(a[x]-1,1);
t2.upd(a[x]-1,a[x]-1);
t2.upd(a[x],-a[x]);
a[x]--;
}
else{
ll w=t1.qry(n+q)-t1.qry(x);
w*=x;
ll w2=t2.qry(n+q)-t2.qry(x);
cout<<w2-w<<"\n";
}
}
return 0;
}