線段樹區間異或

2021-10-03 15:26:12 字數 2016 閱讀 7302

題目描述

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...