線段樹 codevs 1690 開關燈

2022-09-17 05:39:09 字數 1724 閱讀 8076

usaco

時間限制: 1 s

空間限制: 128000 kb

題目等級 : 鑽石 diamond

題目描述 description

輸入描述 input description

第 1 行: 用空格隔開的兩個整數n和m

第 2..m+1 行: 每行表示乙個操作, 有三個用空格分開的整數: 指令號(0代表按下開關,1代表詢問狀態), x 和 y 

輸出描述 output description

第 1..詢問總次數 行:對於每一次詢問,輸出詢問的結果

樣例輸入 sample input

4 50 1 2

0 2 4

1 2 3

0 2 4

1 1 4

樣例輸出 sample output12

1

/*沒什麼好說的,線段樹的區間修改加區間查詢*/2

#define n 100100

3 #include4

using

namespace

std;

5 #include6 #include7

struct

treetree[n*4

];10

intn,m,a,x,y;

11void update(int

k)12

16void build_tree(int k,int l,int

r)17

24int mid=(l+r)>>1,lch=k<<1,rch=(k<<1)+1;25

build_tree(lch,l,mid);

26 build_tree(rch,mid+1

,r);

27update(k);28}

29void down(int

k)30

40void change(int k,int l,int r,int x,int

y)41

49if

(tree[k].delta)

50down(k);

51int mid=(l+r)>>1,lch=k<<1,rch=(k<<1)+1;52

if(x<=mid)

53change(lch,l,mid,x,y);

54if(y>mid)

55 change(rch,mid+1

,r,x,y);

56update(k);57}

58int query(int k,int l,int r,int x,int

y)59

64if

(tree[k].delta)

65down(k);

66int mid=(l+r)>>1,lch=k<<1,rch=(k<<1)+1;67

int ans=0;68

if(x<=mid)

69 ans+=query(lch,l,mid,x,y);

70if(y>mid)

71 ans+=query(rch,mid+1

,r,x,y);

72return

ans; 73}

74int

main()

7585

else printf("

%d\n

",query(1,1

,n,x,y));86}

87return0;

88 }

codevs1690 開關燈 線段樹

這道題需要支援區間修改和區間詢問,因此採用線段樹加以維護。由於求的是開著的燈的數目,因此維護sum 區間 l r 中開著的燈的數目。tag取做0 1,表示區間是否反轉,在進行標記下傳時,如果tag 1,則下傳,否則返回。tag的選取一般跟操作有關 如下 include using namespace...

codevs1080線段樹練習(線段樹)

題目描述 description 一行n個方格,開始每個格仔裡都有乙個整數。現在動態地提出一些問題和修改 提問的形式是求某乙個特定的子區間 a,b 中所有元素的和 修改的規則是指定某乙個格仔x,加上或者減去乙個特定的值a。現在要求你能對每個提問作出正確的回答。1 n 100000,提問和修改的總數m...

codevs 線段樹練習4

題目描述 給你n個數,有兩種操作 1 給區間 a,b 內的所有數都增加x 2 詢問區間 a,b 能被7整除的個數 輸入描述 第一行乙個正整數n,接下來n行n個整數,再接下來乙個正整數q,表示操作的個數.接下來q行每行若干個整數。如果第乙個數是add,後接3個正整數a,b,x,表示在區間 a,b 內每...