題目描述
akn 覺得第一題太水了,不屑於寫第一題,所以他又玩起了新的遊戲。在遊戲中,他發現,這個遊戲的傷害計算有乙個規律,規律如下
擁有乙個傷害串,是乙個長度為 nnn 的只含字元 0 和字元 1 的字串。規定這個字串的首字元是第乙個字元,即下標從 111 開始。
給定乙個範圍 [l, r][l,~r][l, r],傷害為傷害串的這個範圍內中字元 1 的個數
會修改傷害串中的數值,修改的方法是把 [l, r][l,~r][l, r] 中所有原來的字元 0 變成 1,將 1 變成 0。
akn 想知道一些時刻的傷害,請你幫助他求出這個傷害。
輸入格式
輸入的第一行有兩個用空格隔開的整數,分別表示傷害串的長度 nnn,和操作的個數 mmm。
輸入第二行是乙個長度為 nnn 的字串 sss,代表傷害串。
第 333 到第 (m+2)(m + 2)(m+2) 行,每行有三個用空格隔開的整數 op,l,rop, l, rop,l,r。代表第 iii 次操作的方式和區間,規則是:
若 op=0op = 0op=0,則表示將傷害串的 [l, r][l,~r][l, r] 區間內的 0 變成 1,1 變成 0。
若 op=1op = 1op=1,則表示詢問傷害串的 [l, r][l,~r][l, r] 區間內有多少個字元 1。
輸出格式
對於每次詢問,輸出一行乙個整數,代表區間內 1 的個數。
輸入 #1
10 6
1011101001
0 2 4
1 1 5
0 3 7
1 1 10
0 1 4
1 2 6
輸出 #136
1思路:對於區間異或是對線段樹lazy標記的使用,向下查詢的時候,上面部分對於下面部分是由影響的,所以要使用lazy標記。更新的時候重新計算一下每個節點的sum值。
對於乙個區間異或,1的個數就是區間長度減去原來1的個數。
#include
#define maxn 201000
using namespace std;
typedef
long
long ll;
struct node
tree[maxn<<2]
;int n,m,op,x,y;
char str[maxn]
;void
build
(int id,
int l,
int r)
int mid=
(l+r)
>>1;
build
(id<<
1,l,mid)
;build
(id<<1|
1,mid+
1,r)
; tree[id]
.sum=tree[id<<1]
.sum+tree[id<<1|
1].sum;
}void
pushup
(int id)
void
pushdown
(int id)
}void
update
(int id,
int l,
int r)
int mid=
(tree[id]
.l+tree[id]
.r)>>1;
pushdown
(id);if
(l<=mid)
update
(id<<
1,l,r);if
(r>mid)
update
(id<<1|
1,l,r)
;pushup
(id);}
intquery
(int id,
int l,
int r)
intmain()
return0;
}
關於區間異或的線段樹
題 題意 倆個操作,操作1 l,r,x 區間 l,r 的數全部異或上x。操作2 l r 輸出區間 l,r 和 分析 對陣列a建線段樹,對於線段樹的每乙個節點進行二進位制拆位,每個位就統計有多少個1,更新操作對於涵蓋區間的二進位制位就等於其長度減去更新前的1的個數 includeusing names...
線段相交的異或值 (線段樹 or 優先佇列)
vvq 最近迷上了線段這種東西 現在他手上有 n 條線段,他希望在其中找到兩條有公共點的線段,使得他們的異或值最大。定義線段的異或值為它們並的長度減他們交的長度 第一行包括乙個正整數 n,表示 vvq 擁有的線段條數。接下來 n 行每行包括兩個正整數 l,r,表示 vvq 擁有的線段的 左右端點。一...
線段樹(區間樹)
目錄 為什麼要使用線段樹 什麼是線段樹 線段樹融合介面 線段樹實現 線段樹例題 融合介面 author administrator param public inte ce merger package com.suanfa.segmenttree 線段樹 區間樹 author administra...