[BZOJ 3585]mex

外面一定要套一層莫隊的不用說QAQ

學會分析時間複雜度OTZ

按照權值來說,我們需要維護一些數據結構

比如樹狀數組(查詢時二分??)  -----O(msqrt(n)logn)

比如分塊(修改O(1)查詢(sqrt(n)))-----O(msqrt(n))


這裏寫了一份分塊。

樹狀數組的話可以按照權值的有無來二分。


#include 
#include 
#include 
#include 
#include 
#define maxn 200010
using namespace std;

int n, m;

int a[maxn], pos[maxn];

struct opt{
	int l, r, id;
	bool operator<(const opt& k)const{
		if(pos[l] != pos[k.l])return pos[l] < pos[k.l];
		return r < k.r;
	}
}q[maxn];

int ans[maxn];

struct block{
	int sum, cnt, l, r, wy;
	int vis[500];
	
	void build(int l, int r){
		sum = r - l + 1;
		this->l = l, this->r = r;
		wy = l - 1;
		memset(vis, 0, sizeof vis);
	}
	
	void modify(int p, int type){
		p -= wy;
		if(type == 1){
			if(!vis[p])cnt ++;
			vis[p] ++;
		}
		else{
			vis[p] --;
			if(!vis[p])cnt --;
		}
	}
	
	bool empty(){return sum == cnt;}
	
	int ask(){
		for(int i = 1; i <= sum; i ++)
		    if(!vis[i])return i + wy;
	}
}b[500];

int main(){
	scanf("%d%d", &n, &m);
	for(int i = 1; i <= n; i ++)
	    scanf("%d", &a[i]);
    int blo = sqrt(n) + 1;
	for(int i = 1; i <= blo; i ++){
		int L = (i - 1) * blo + 1, R = i * blo;R = min(R, n);
		if(i == 1)L = 0;
		if(L > R){blo = i;break;}
		for(int j = L; j <= R; j ++)
			pos[j] = i;
		b[i].build(L, R);
	}
	for(int i = 1; i <= m; i ++){
		scanf("%d%d", &q[i].l, &q[i].r);
		q[i].id = i;
	}
	sort(q + 1, q + 1 + m);
	int l = 1, r = 0;
	for(int i = 1; i <= m; i ++){
		for(; l < q[i].l; l ++){
			if(a[l] > n)continue;
			b[pos[a[l]]].modify(a[l], -1);
		}
		for(; l > q[i].l; l --){
            if(a[l - 1] > n)continue;
			b[pos[a[l - 1]]].modify(a[l - 1], 1);
		}
		for(; r < q[i].r; r ++){
            if(a[r + 1] > n)continue;
			b[pos[a[r + 1]]].modify(a[r + 1], 1);
		}
		for(; r > q[i].r; r --){
            if(a[r] > n)continue;
			b[pos[a[r]]].modify(a[r], -1);
		}
		int ret = 0;
		for(int j = 1; j <= blo; j ++)
		    if(!b[j].empty()){
				ret = b[j].ask();
				break;
		    }
		ans[q[i].id] = ret;
	}
	for(int i = 1; i <= m; i ++)
	    printf("%d\n", ans[i]);
	return 0;
}



發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章