kuangbin训练专题——莫队

// 注意:修改和原始数据同时需要离线如何处理
// add和del函数认真思考
#include<bits/stdc++.h>

using namespace std;
const int N = 2e5+10, len = 2100;
int n, m;
int tmp = 0;
array<int, 4> que[N];
array<int, 2> change[N];
int c[N], cnt[N], ans[N];
vector<int> nums;
int id1[N], id2[N], st[N];

int main(){
	scanf("%d %d", &n, &m);
	for(int i = 1; i <= n; i ++) scanf("%d", &c[i]), nums.push_back(c[i]);
	int qcnt = 0, chcnt = 0;
	for(int i = 1; i <= m; i ++){
		int op; scanf("%d", &op);
		if(op == 1){
			int l, r; scanf("%d %d", &l, &r);
			que[++qcnt] = {l, r, chcnt, qcnt};
		}
		else if(op == 2){
	        int p, col; scanf("%d %d", &p, &col);
	        change[++chcnt] = {p, col};	
	        nums.push_back(col);		
		}
	}

	sort(nums.begin(), nums.end());
	nums.erase(unique(nums.begin(), nums.end()), nums.end());

	for(int i = 1; i <= n; i ++){
		id1[i] = lower_bound(nums.begin(), nums.end(), c[i]) - nums.begin();
	}
	for(int i = 1; i <= chcnt; i ++){
		id2[i] = lower_bound(nums.begin(), nums.end(), change[i][1]) - nums.begin();
	}

	sort(que + 1, que + qcnt + 1, [&](array<int, 4> a, array<int, 4> b){
	    // l分块,r分块,t递增排序
	    int l1 = a[0] / len, l2 = b[0] / len;
	    int r1 = a[1] / len, r2 = b[1] / len;
	    if(l1 != l2) return l1 < l2;
	    else if(r1 != r2) return r1 < r2;
	    else return a[2] < b[2];
	});

	tmp = 1;
	auto add = [&](int x){
		cnt[x] ++;
		st[cnt[x] - 1] --;
		st[cnt[x]] ++;
		if(st[cnt[x] - 1] == 0 && cnt[x] - 1 < tmp) tmp = cnt[x] - 1;
		while(st[tmp]) tmp ++;
	};
	auto del = [&](int x){
		cnt[x] --;
		st[cnt[x] + 1] --;
		st[cnt[x]] ++;
		if(st[cnt[x] + 1] == 0 && cnt[x] + 1 < tmp) tmp = cnt[x] + 1;
		while(st[tmp]) tmp ++;
	};

	int l = 1, r = 0, t = 0;
	for(int i = 1; i <= qcnt; i ++){
	    while(r < que[i][1]) r ++, add(id1[r]);
	    while(l > que[i][0]) l --, add(id1[l]);
	    while(r > que[i][1]) del(id1[r]), r --;
	    while(l < que[i][0]) del(id1[l]), l ++;
	    // 这里是<,==说明是满足条件的
	    while(t < que[i][2]){
	        t ++;
	        int pos = change[t][0];
	        if(l <= pos && r >= pos){
	            del(id1[pos]);
	            swap(c[pos], change[t][1]);
	            swap(id1[pos], id2[t]);
	            add(id1[pos]);
	        }
	        else swap(c[pos], change[t][1]), swap(id1[pos], id2[t]);
	    }
	    while(t > que[i][2]){
	        int pos = change[t][0];
	        if(l <= pos && r >= pos){
	            del(id1[pos]);
	            swap(c[pos], change[t][1]);
	            swap(id1[pos], id2[t]);
	            add(id1[pos]);
	        }
	        else swap(c[pos], change[t][1]), swap(id1[pos], id2[t]);
	        t --;          
	    }
	    ans[que[i][3]] = tmp;
	}
	for(int i = 1; i <= qcnt; i ++) printf("%d\n", ans[i]);

}

posted @ 2022-04-29 19:21  牛佳文  阅读(32)  评论(0编辑  收藏  举报