树状数组二分求调quq
查看原帖
树状数组二分求调quq
1036683
Eeezoe楼主2024/11/20 18:32
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef long double ld;
typedef __int128 i128;

mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
const int N=1e5+1e6+10;
struct FWK{
	vector<int> f;
	#define lb(x) x&(-x)
	inline void init(){f.resize(N);}
	inline void update(int i,int x){
		for(;i<N;i+=lb(i)) f[i]+=x;
	}
	inline int rnk(int x){
		int res=1;--x;
		while(x){
			res+=f[x];x-=lb(x);
		}return res;
	}
	inline int kth(int k,int n){
		int pos=0;
		for(int i=__lg(n)+1;i>=0;i--){
			if(pos+(1<<i)<n && f[pos+(1<<i)]<k){
				k-=f[pos+(1<<i)];pos+=(1<<i);
			}
		}return pos;
	}
	inline int front(int x,int n){
		return kth(rnk(x)-1,n);
	}
	inline int back(int x,int n){
		return kth(rnk(x+1),n);
	}
};
#define AII array<int,2>
int main(){
	ios::sync_with_stdio(false);
	cin.tie(nullptr);
	int n,q;cin>>n>>q;
	vector<int> a(n+1),b;
	for(int i=1;i<=n;i++){
		cin>>a[i];
		b.push_back(a[i]);
	}
	vector<AII> ask(q+1);
	for(int i=1;i<=q;i++){
		auto &[op,x]=ask[i];
		cin>>op>>x;
		if(op!=4) b.push_back(x);
	}
	sort(b.begin(),b.end());
	b.erase(unique(b.begin(),b.end()),b.end());
	FWK fwk;fwk.init();
	for(int i=1;i<=n;i++){
		a[i]=lower_bound(b.begin(),b.end(),a[i])-b.begin()+1;
		fwk.update(a[i],1);
	}int ans=0,ls=0,ln=b.size();
	for(int i=1;i<=q;i++){
		auto [op,x]=ask[i];
		x^=ls;int tmp=0;
		if(op!=4){
			x=lower_bound(b.begin(),b.end(),x)-b.begin()+1;
		}
		if(op==1) fwk.update(x,1);
		
		if(op==2) fwk.update(x,-1);
		
		if(op==3){tmp=fwk.rnk(x);}
		
		if(op==4){tmp=b[fwk.kth(x,ln)];}
		
		if(op==5){tmp=b[fwk.front(x,ln)];}
		
		if(op==6){tmp=b[fwk.back(x,ln)];}
		if(op>2) {ans^=tmp;ls=tmp;}
		
	}cout<<ans<<"\n";
	return 0;
}

//cout << fixed << setprecision(x);
2024/11/20 18:32
加载中...