1. 程式人生 > 其它 >線段樹例題Part 1

線段樹例題Part 1

這裡是幾道線段樹的入門題目,難度多在(普及+提高-)附近,如果對模板掌握的好的話可以直接跳過這裡。

1、開關

特殊的懶標記。

題目中每個節點都是開關,只有開或者關兩種狀態,很容易想到如果對一個序列連續操作兩次,等於沒有操作,所以在區間更新時用到異或的操作。

用一個bool型的數儲存每個節點的懶標記,對懶標記進行更新就是把這個數取反。把懶標記與1異或,如果懶標記的數是1,因為二進位制下相等,所以得到0;如果0與1異或,二進位制下不相等,得到1。這樣就起到了取反的操作。

下一個要解決的問題,是區間修改。

其實很好想,區間裡的開關,不是開就是關,題目要求開啟的開關數,如果區間修改就把開啟的開關數變成此時關閉的開關數就行了。

區間的總開關數-區間開啟的開關數=區間關閉的開關數

雙倍經驗:P2574 XOR的藝術

 1 #include <bits/stdc++.h>
 2 using namespace std;
 3 const int maxn=2e5+10;
 4 int n,m;
 5 struct tree
 6 {
 7     int l,r;
 8     int sum;
 9     int teg;//懶標記(沒有用bool型) 
10 }s[maxn*4];
11 void pushup(int pos){s[pos].sum=s[pos*2].sum+s[pos*2+1].sum;}
12 void build(int pos,int l,int r) 13 { 14 s[pos].l=l;s[pos].r=r;s[pos].sum=s[pos].teg=0;//開關初始全是關的 15 if(l==r) return; 16 int mid=(l+r)/2; 17 build(pos*2,l,mid);build(pos*2+1,mid+1,r); 18 }//標準的建樹操作 19 void pushdown(int pos) 20 { 21 if(s[pos].teg)//如果懶標記為true 22 { 23 s[pos].teg=0
; 24 s[pos*2].teg^=1;s[pos*2+1].teg^=1;//左右子樹的懶標記對1異或 25 s[pos*2].sum=s[pos*2].r-s[pos*2].l+1-s[pos*2].sum; 26 s[pos*2+1].sum=s[pos*2+1].r-s[pos*2+1].l+1-s[pos*2+1].sum;//更新方法同change 27 } 28 } 29 void change(int pos,int l,int r) 30 { 31 if(s[pos].l>=l&&s[pos].r<=r) 32 { 33 s[pos].sum=(s[pos].r-s[pos].l+1)-s[pos].sum;//區間開個數變成區間關個數 34 s[pos].teg^=1;//懶標記與1異或 35 return ; 36 } 37 pushdown(pos);//懶標記下傳 38 int mid=(s[pos].l+s[pos].r)/2; 39 if(mid>=l) change(pos*2,l,r);if(mid<r) change(pos*2+1,l,r); 40 pushup(pos);//更新節點值 41 } 42 int ask(int pos,int l,int r) 43 { 44 if(s[pos].l>=l&&s[pos].r<=r) return s[pos].sum; 45 pushdown(pos); 46 int mid=(s[pos].l+s[pos].r)/2,val=0; 47 if(l<=mid) val+=ask(pos*2,l,r); 48 if(r>mid) val+=ask(pos*2+1,l,r); 49 return val; 50 }//和模板完全一直的區間查詢 51 int main() 52 { 53 cin>>n>>m;build(1,1,n); 54 while(m--) 55 { 56 int opt,x,y; 57 cin>>opt>>x>>y; 58 if(!opt) change(1,x,y); 59 else cout<<ask(1,x,y)<<endl;//按照題目要求進行操作 60 } 61 return 0;程式碼
程式碼

2、守墓人

純模板線段樹。

維護區間和。

支援區間和單點修改和查詢

3、忠誠

也是純模板線段樹。

維護區間最值。

支援區間最值查詢。

其實線段樹的黃題大多數都是不需要思維的模板題,所以只需要熟悉最基本的操作就行,無需過多刷題。

————THE END

by AIskeleton 2021/12/22