【題解】Luogu P2605 [ZJOI2010]基站選址_weixin_取模

代碼

#include <bits/stdc++.h>
#define ls(p) ((p) << 1)
#define rs(p) (((p) << 1) | 1)
#define mid ((l + r) >> 1)
using namespace std;
typedef long long ll;
typedef pair<int,int> pii;
const int N = 600 + 5,M = 5e5,mod = 998244353;
int n,c;
multiset<int> s,res;
map<int,int> cnt;
map<pair<int,int>,int> m;
int find(int x,bool f){//f 表示 x 是否在集合內
	if(x == -1) return -1;
	auto it = s.upper_bound(c - 1 - x); 
	if(it == s.begin()) return -1;
	it--;
	if(*it == x && cnt[x] == 1 && f){
		if(it == s.begin()) return -1;
		it--;
	}
	return *it;
}
void insert(int x){
	int y = find(x,0),z = find(y,1);
	if(y != -1 && z <= x){
		if(m[{min(y,z),max(y,z)}]){
			res.erase(res.find(y + z));
			m[{min(y,z),max(y,z)}] = false;
		}
		m[{min(y,x),max(y,x)}] = true;
		res.insert(x + y);
	}
	s.insert(x);
	cnt[x]++;
}
void erase(int x){
	int y = find(x,1),z = find(y,1);
	s.erase(s.find(x));
	cnt[x]--;
	if(z == x){
		if(m[{min(y,x),max(y,x)}]){
			res.erase(res.find(x + y));
			m[{min(y,x),max(y,x)}] = false;
		}
		z = find(y,1);
		int k = find(z,1);
		if(z != -1 && k <= y){
			res.insert(z + y);
			m[{min(y,z),max(y,z)}] = true; 
		}
	}
}
int ask(){
	if(s.size() < 2){
		return -1;
	}
	int ans = max(*s.rbegin() + *next(s.rbegin()) - c,res.size() == 0 ? 0 : *res.rbegin());
	return ans;
}
int main(){
	ios::sync_with_stdio(false);
	cin.tie(0);
//	freopen("in.txt","r",stdin);
//	freopen("out.txt","w",stdout);
	cin>>n>>c;
	int l = 0;
	while(n--){
		int op,x;
		cin>>op>>x;
		x ^= l;
		x %= c;
		if(op == 1){
			insert(x);
		}else{
			erase(x);
		}
		int ans = ask();
		if(ans == -1){
			l = 0;
			cout<<"EE\n";
		}else{
			l = ans;
			cout<<ans<<'\n';
		}
	}
	return 0;
}