區間MEX 線段樹維護mex陣列

2021-08-09 06:41:21 字數 2566 閱讀 6872

問題描述

給你乙個長度為n的數列,元素編號1到n,第i個元素值為ai。現在有m個形如(l,r)的提問,你需要回答出區間[l,r]的mex值。即求出區間[l,r]中沒有出現過的最小的非負整數。

輸入格式

第一行,兩個整數n和m

第二行,n個空格間隔的整數,表示數列a

接下來m行,每行兩個整數l,r,表示一次詢問

輸出格式

m行,每行乙個整數,表示對應詢問的答案。

樣例輸入

7 5

0 2 1 0 1 3 2

1 3

2 3

1 4

3 6

2 7

樣例輸出

3

0 3 2 4

資料範圍

1<=n,m<=200000

0<=ai<=200000

1<=l<=r<=n

由於沒有修改操作,可以考慮離線演算法。

首先考慮暴力的做法。對於固定的左端點,如何用o(

n)的方法求出左端點與右端點形成的mex陣列的值?用乙個mark陣列從下到大依次列舉沒有出現過的數值即可。考慮到mex陣列單調不減均攤時間複雜度o(

n)。如果詢問區間的左端點只有乙個,那麼就能像這樣o(

n)解決。

然而本題的左端點是任意的。但是根據離線演算法的基本操作,我們可以把討論有序化。不妨將詢問按左端點從小到大排序。現在假設我們已經求出了以i為左端點的所有區間的mex值,想要得到以i+1為左端點的所有區間的mex值,考慮兩種狀態如何轉移。

從i到i+1,只有乙個不同:那就是有些區間裡本來有ai

但現在沒有了。顯然只有這樣的區間才會受到一定影響。「這樣的區間」是哪些區間呢?在以i+1為左端點的區間中,這樣的區間是右端點在下乙個ai

出現前的區間,用乙個鍊錶可以方便地維護。

這些區間會受到怎樣的影響?考慮ai

與mex

j 的大小關係。如果me

xj比a

i 要大,那麼把me

xj更新為ai

;否則ai

就不會對me

xj的值產生影響。這樣做問題就解決了。處理區間修改問題,使用線段樹。

1預處理:

(1)用o(

n)將以1為左端點的mex值預處理出來;

(2)預處理出每個數下一次出現的位置;

(3)按區間左端點將詢問排序;

2.從1到n由小到大討論。處理完以i為左端點的詢問後,對me

x 陣列進行區間修改。

**:

#include#include#include#define maxm 200005

#define maxn 200005

#define maxt 800005

using namespace std;

int n,m,a[maxn],mex[maxn],ans[maxm],nex[maxn],las[maxn];

bool mark[maxn];

struct nodeqry[maxm];

bool operator<(node x,node y)

int build(int x,int y)

ls[p]=build(x,mid);

rs[p]=build(mid+1,y);

v[p]=min(v[ls[p]],v[rs[p]]);

return p;

}void modify(int p,int l,int r,int k)

int mid=a[p]+b[p]>>1;

modify(ls[p],l,r,k);

modify(rs[p],l,r,k);

}int getans(int p,int k)

int main()

for(i=1;i<=m;i++)scanf("%d%d",&qry[i].l,&qry[i].r),qry[i].id=i;

for(i=1;i<=n;i++)

sort(qry+1,qry+m+1);

memset(lazy,-1,sizeof(lazy));

build(1,n);

for(i=1,j=1;i<=n&&j<=m;i++)

modify(1,1,nex[i]-1,a[i]);

}for(i=1;i<=m;i++)printf("%d\n",ans[i]);

}

hdu 4747 Mex 線段樹區間更新

有大神部落格在。mex有兩個特徵,乙個是最小,乙個是不在集合中 首先可以看出mex是遞增的 刪掉乙個數a i 對mex l,r r對l i的影響是,a i 不在集合中了,在a i 下次出現之前,那些大於a i 的mex j 都可以被減小至a i 話說線段樹區間更新每次都寫挫 一開始pushdown ...

mex(線段樹 離散化)

題目描述 給你乙個無限長的陣列,初始的時候都為0,有3種操作 操作1是把給定區間 l,r l,r l,r 設為1,操作2是把給定區間 l,r l,r l,r 設為0,操作3把給定區間 l,r l,r l,r 0,1反轉。l r 一共n個操作,每次操作後要輸出最小位置的0。l,r 題解 l r 經過分...

Mex(線段樹的巧妙應用)

題目要求求某段區間第乙個沒有出現的數 0,1,2,3.對於所有的區間,我們把這樣的數加起來最後得到乙個結果。首先,我們要求出這樣的數,然後還得列舉出所有的區間,複雜度太大了。換種思路,我們定住l,是不是一次效能求出所有的r所得出的結果,這就用到線段樹的性質了,因為在移動l的過程中,移一步只變化乙個數...