卡常求调,玄关
查看原帖
卡常求调,玄关
1160620
ghy_jerami__楼主2024/11/8 09:20

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;
}
2024/11/8 09:20
加载中...