線段樹專題

2021-09-29 08:18:59 字數 1583 閱讀 8559

題意:給定n個數 a1,

a2,…

,a

na_1,a_2,\dots,a_n

a1​,a2

​,…,

an​,給出q個詢問求[l,r]內所有子區間的異或和。比如,陣列1,2,3中[1,3]的異或和為:1+1

xor2

+1xo

r2xo

r3+2

+2xo

r3+3

1+1xor2+1xor2xor3+2+2xor3+3

1+1xor

2+1x

or2x

or3+

2+2x

or3+

3思路:題目要我們求異或和,因此我們需要將每乙個a

ia_i

ai​拆分成二進位制位。把每個數的每一位提出來後,我們需要統計出現奇數個1的區間。

對於區間的合併,我們需要統計的是:左邊奇數個1的區間數+右邊奇數個1區間+橫跨兩邊的奇數個1的區間數。

而橫跨兩邊的答案就是:左邊以mid結尾的奇數個1的區間數 ×

\times

× 右邊以mid+1為開頭的偶數個1的區間數+左邊以mid結尾的偶數個1的區間數×

\times

×右邊以mid+1為開頭的奇數個1的區間數

#include 

#include

#include

#define ls (rt<<1)

#define rs (

(rt<<1)

|1)#define ll long

long

using namespace std;

const

int maxn=

1e5+

5,inf=

0x3f3f3f3f

;const

int mod=

1e9+7;

int t,n,q;

int a[maxn]

;struct node

st[maxn<<2]

;node merge

(node a,node b)

ret.len=a.len+b.len;

return ret;

}void

build

(int rt,

int l,

int r)

st[rt]

.len=1;

return;}

int mid=

(l+r)

>>1;

build

(ls,l,mid)

;build

(rs,mid+

1,r)

; st[rt]

=merge

(st[ls]

,st[rs]);

}node query

(int rt,

int l,

int r,

int l,

int r)

}int

main()

}return0;

}

線段樹專題

最最基礎的線段樹,只更新葉子節點,然後把資訊用pushup int r 這個函式更新上來。hdu1166 敵兵布陣 線段樹 hdu 1166 敵兵布陣 單點更新區間求和 hdu1754 i hate it 線段樹 hdu 1754 i hate it 單點更新 區間求最值 hdu1394 minim...

線段樹專題

敵兵布陣 單點更新,區間求和查詢 include include include include include using namespace std const int maxn 5e4 5 struct nodet maxn 4 int a maxn nsum void build int x...

ACM 線段樹 專題

其中應該有我以前 刷過的題吧 沒有辦法 演算法這東西 一不刷 就會忘。像這道題 我 就wa了 四發 才過 但是 我 以前確實過過。再重新理解一下吧 大概就是 線段樹 就是 左右 節點 然後 上面就是 我們的 和 建立的時候和每次修改 都要更新一下父節點 也就是子節點的和 樹這個東西 仔細想想 確實集...