rt,写的树状数组 + 线段树,t 了最后三个点
#include<bits/stdc++.h>
using namespace std;
const int N = 100100;
int n,m,le[N],ri[N],ans[N];
bool mp[N];
struct Bit{
int tree[N];
int lowbit(int x){return x & (-x);}
inline void updata(int x,int d){
int u=x;
while(u<=n){
tree[u]+=d;
u+=lowbit(u);
}
return;
}
int query(int x){
int u=x,ans=0;
while(u>0){
ans+=tree[u];
u-=lowbit(u);
}
return ans;
}
};
Bit sum,entour;
struct Segtree{
vector <int> tree[N*4];
inline void updata(int l,int r,int L,int R,int x,int d){
if(l>=L && r<=R){
tree[x].push_back(d);
return;
}
int mid=l+r>>1;
if(mid>=L) updata(l,mid,L,R,x*2,d);
if(mid+1<=R) updata(mid+1,r,L,R,x*2+1,d);
return;
}
inline void add(int l,int r,int d,int x){
for(int i=0;i<tree[x].size();i++){
int id=tree[x][i];
while(entour.query(ri[id])-entour.query(le[id]-1)){
ans[id]++;
sum.updata(id,1);
le[id]=min((ans[id]-1)*id+1,n+1),ri[id]=min(ans[id]*id,n+1);
}
if(le[id]<=n) updata(1,n,le[id],ri[id],1,id);
}
tree[x].clear();
if(l==r) return;
int mid=l+r>>1;
if(mid>=d) add(l,mid,d,x*2);
if(mid+1<=d) add(mid+1,r,d,x*2+1);
return;
}
}segtree;
signed main(){
ios::sync_with_stdio(false);
cin.tie(0); cout.tie(0);
cin>>n>>m;
for(int i=1;i<=n;i++){
ans[i]=1,le[i]=1,ri[i]=i;
segtree.updata(1,n,le[i],ri[i],1,i);
sum.updata(i,1);
}
while(m--){
int op,x,y;
cin>>op;
if(op==1){
cin>>x;
if(mp[x]) continue;
mp[x]=true;
entour.updata(x,1);
segtree.add(1,n,x,1);
}else{
cin>>x>>y;
cout<<sum.query(y)-sum.query(x-1)<<'\n';
}
}
return 0;
}