牛客練習賽53 老瞎眼 pk 小鮮肉 線段樹思維

2021-10-17 03:47:24 字數 2220 閱讀 9709

傳送門

給定長度為n

nn的陣列,q

qq個詢問

每次問[l,

r]

[l,r]

[l,r

]內最小的區間長度[l,

r]

[l,r]

[l,r

]使得al⊕

al+1

...⊕

ar=0

a_l\oplus a_...\oplus a_=0

al​⊕al

+1​.

..⊕a

r​=0

明顯需要預處理

如果做乙個異或字首和pre

[x

]pre[x]

pre[x]

那麼問題就轉化為[l−

1,r]

[l-1,r]

[l−1,r

]找到最小的區間[l,

r]

[l,r]

[l,r

]滿足pre

[l]⊕

pre[

r]

pre[l]\oplus pre[r]

pre[l]

⊕pre

[r]

此時區間為[l+

1,r]

[l+1,r]

[l+1,r

] 就是找兩個最相近的數,似乎不是很好弄

考慮離線做法,如果按照r

rr端點排序

那就維護乙個變數idid

id一路加到r

rr去,期間一直更新前面那些相同的數

也就是讓w[i

]w[i]

w[i]

表示a

ia_i

ai​和右邊第乙個和a

ia_i

ai​相同的數的距離l,

r]

[l,r]

[l,r]中

因為按照r

rr排序,所以端點r

rr滿足

因為查詢線段樹實在[l,

r]

[l,r]

[l,r

],所以左端點也滿足

#include

using

namespace std;

#define mid (l+r>>1)

#define ls (rt<<1)

#define rs (rt<<1|1)

#define lson ls,l,mid

#define rson rs,mid+1,r

const

int maxn =

2e6+10;

const

int inf =

1e9;

struct p

}d[maxn]

;int a[maxn]

,last[maxn]

;int w[maxn]

,n,q,ans[maxn]

;void

build

(int rt,

int l,

int r)

void

update

(int rt,

int l,

int r,

int index,

int val)

update

(lson,index,val)

;update

(rson,index,val)

; w[rt]

=min

( w[ls]

,w[rs]);

}int

ask(

int rt,

int l,

int r,

int l,

int r)

intmain()

for(

int i=

1;i<=q;i++

)sort

( d+

1,d+

1+q )

;int num =1;

build(1

,1,n+1);

for(

int i=

1;i<=q;i++

) ans[d[i]

.id]

=ask(1

,1,n,d[i]

.l,d[i]

.r );}

for(

int i=

1;i<=q;i++

)}

牛客練習賽53 E 老瞎眼 pk 小鮮肉

problem 這題的題意大概是 給出一段長度為 n 的區間 q 次詢問求 l r 這個區間內 最短的一段區間 l r 使得 oplus a j 0 l l 誒 離線麼?樹狀陣列好像不好做啊 因為大多數人只會單點修改區間修改和差分吧 考慮離線 線段樹 我們先記錄乙個 sum i oplus i a ...

老瞎眼 pk 小鮮肉 線段樹 區間離線

題意 給出一段長度為n的序列,q次查詢區間 l,r 內異或為0最短子區間長度。思路 假設區間 l,r 異或為0,那麼 1,l 1 的異或值等於 1,r 的異或值。那麼對於每個點,我們存以它為右端點的區間異或值為0的最短區間長度,再將查詢區間按右端點公升序排列。然後利用線段樹,從左到右遍歷 在這個點對...

牛客練習賽53 ABC

a 簡單dp include define ll long long using namespace std const ll mod 1e9 7 ll d 1000000 2 ll n intmain cout d n 1 d n 0 mod return0 b 分塊 include define...