mex(線段樹 離散化)

2022-07-22 12:27:12 字數 3423 閱讀 4017

題目描述:

給你乙個無限長的陣列,初始的時候都為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]'>經過分析觀察,可以發現,答案只有可能是[l

,r]'>1,l

,r+1

'>1,l,r+1

[l,

r]'>1,l

,r+1

'>

[l

,r]'>1,l

,r+1

'>所以我們開乙個陣列記錄1,以及所有的l,r,r+1,並離散化[l

,r]'>1,l

,r+1

'>然後用線段樹模擬操作即可[l

,r]'>1,l

,r+1

'>這裡有兩種思路:[l

,r]'>1,l

,r+1

'>一種是記錄某一區間內0的最小位置和1的最小位置,反轉時互換兩個位置

#include#include

#include

using

namespace

std;

typedef

long

long

ll;const

int n=1e5+5

;const

int maxn=3e5+5

;int

n,m;ll a[maxn];

struct

queq[n];

int s0[maxn<<2],s1[maxn<<2],lazy[maxn<<2],rev[maxn<<2

];void pushup(int

u)void build(int u,int l,int

r)

int mid=(l+r)/2

; build(u*2

,l,mid);

build(u*2+1,mid+1

,r);

pushup(u);

}void pushdown(int u,int l,int

r)

else

if(lazy[u]==0

) lazy[u]=-1

; }

if(rev[u])

}void update(int u,int l,int r,int a,int b,int

k) pushdown(u,l,r);

int mid=(l+r)/2

;

if(a<=mid) update(u*2

,l,mid,a,b,k);

if(b>mid) update(u*2+1,mid+1

,r,a,b,k);

pushup(u);

}void revere(int u,int l,int r,int a,int

b) pushdown(u,l,r);

int mid=(l+r)/2

;

if(a<=mid) revere(u*2

,l,mid,a,b);

if(b>mid) revere(u*2+1,mid+1

,r,a,b);

pushup(u);

}int

main()

sort(a+1,a+n+1

); n=unique(a+1,a+1+n)-a-1

; build(

1,1,n);

for(int i=1;i<=m;i++)

else

if(q[i].op==2

)

else

if(!s0[1]) printf("

%lld\n

",a[n]+1

);

else printf("

%lld\n

",a[s0[1

]]);

}return0;

}

另一種是記錄某一區間內1的個數,查詢時如果乙個區間內1的個數小於這個區間的總個數,則說明這個區間內有0,遞迴下去

#include#include

#include

using

namespace

std;

typedef

long

long

ll;const

int n=1e5+5

;const

int maxn=3e5+5

;int

n,m;ll a[maxn];

struct

queq[n];

int sum[maxn<<2],lazy[maxn<<2],rev[maxn<<2

];void build(int u,int l,int

r)void pushdown(int u,int l,int

r)

else

lazy[u]=-1

; }

if(rev[u])

//還是錯誤2

}void update(int u,int l,int r,int a,int b,int

p)

else

else

if(p==2

)

else

//錯誤2:lazy,rev是會相互影響的

}

return

; }

pushdown(u,l,r);

int mid=(l+r)/2

;

if(a<=mid) update(u*2

,l,mid,a,b,p);

if(b>mid) update(u*2+1,mid+1

,r,a,b,p);

sum[u]=sum[u*2]+sum[u*2+1];}

ll query(

int u,int l,int

r)int

main()

sort(a+1,a+n+1

); n=unique(a+1,a+1+n)-a-1

; build(

1,1,n);

for(int i=1;i<=m;i++)

return0;

}

離散化 線段樹

題目 分析 每次1操作會往序列底加first個second,first 和 second 都是最大1e9的資料,每次2操作詢問序列中第first到第second個數的和 一開始就感覺有點像線段樹,輸入資料太大我們可以離線處理把資料離散化下,然後扔到線段樹上,維護兩個陣列 sum 區間數的值的和 nu...

資料離散化 線段樹

前言 遇到了乙個矩形面積堆疊的問題,想了很久。終於找到了方法。先做個小記,待到具體問題時再分析。資料離散化 高大上的名字,其實就是對資料的一種處理,也可以採取陣列 或者 容器 map vector。之類的來儲存。之前的ibm技術俱樂部主席競選 那道題其實就是很好的應用。有些資料本身很大,自身無法作為...

紙帶 線段樹 離散化

題目大意 每次給一段區間染色,求最後整個區間有多少種顏色 分析 用膝蓋想也知道這題線段樹可以輕鬆水過,於是出題人靈機一動,挖了個深坑,每次給的區間是左開右閉的,但題目沒說,他給了你一張圖,你們可以感受一下 於是正解wa成0分我也是很絕望的。有一點要注意一下,離散化後有些區間會並在一起,原來中間的顏色...