BZOJ4631 踩氣球 題解(線段樹)

2022-03-26 10:28:02 字數 1538 閱讀 4859

題目鏈結

題目大意:給定乙個長度為$n$的序列$$。現在有$m$個區間$[l_i,r_i]$和$q$個操作,每次選取乙個$x$使得$a_x--$。問每一次操作後區間和為$0$的區間個數。

可以用主席樹解決,但蒟蒻不會,蒟蒻只會寫線段樹qaq。

對於每乙個區間$[l_i,r_i]$,我們可以把它分解成線段樹上$s$個區間,線段樹每個結點維護乙個向量陣列,用來存包含它的區間。當某乙個$a_x--$後,看線段樹上區間和是否為0,如果是那麼包含這個區間的區間$s--$。如果$s=0$那麼$ans++$。

注意$update$向上回溯時也要判斷一下是否為0,進行更新。

時間複雜度$o((m+q)\log n+n)$。

**:

#includeusing

namespace

std;

int n,q,m,a[100005

],ans;

struct

node

tree[

500005

];struct

node

t[100005

];inline

intread()

while(isdigit(ch))

return x*f;

}inline

void build(int index,int l,int

r)

int mid=(l+r)>>1

; build(index*2

,l,mid);

build(index*2+1,mid+1

,r);

tree[index].val=tree[index*2].val+tree[index*2+1

].val;

}inline

void update(int index,int pos,int

v) }

return

; }

int mid=(tree[index].l+tree[index].r)>>1

;

if (pos<=mid) update(index*2

,pos,v);

else update(index*2+1

,pos,v);

tree[index].val=tree[index*2].val+tree[index*2+1

].val;

if (tree[index].val==0

)

}}inline

void split(int index,int l,int r,int

id)

int mid=(tree[index].l+tree[index].r)>>1

;

if (l<=mid) split(index*2

,l,r,id);

if (r>mid) split(index*2+1

,l,r,id);

}int

main()

return0;

}

463 島嶼的周長

給定乙個包含 0 和 1 的二維網格地圖,其中 1 表示陸地 0 表示水域。網格中的格仔水平和垂直方向相連 對角線方向不相連 整個網格被水完全包圍,但其中恰好有乙個島嶼 或者說,乙個或多個表示陸地的格仔相連組成的島嶼 島嶼中沒有 湖 湖 指水域在島嶼內部且不和島嶼周圍的水相連 格仔是邊長為 1 的正...

463 島嶼的周長

給定乙個包含 0 和 1 的二維網格地圖,其中 1 表示陸地 0 表示水域。網格中的格仔水平和垂直方向相連 對角線方向不相連 整個網格被水完全包圍,但其中恰好有乙個島嶼 或者說,乙個或多個表示陸地的格仔相連組成的島嶼 島嶼中沒有 湖 湖 指水域在島嶼內部且不和島嶼周圍的水相連 格仔是邊長為 1 的正...

463 島嶼的周長

給定乙個包含 0 和 1 的二維網格地圖,其中 1 表示陸地 0 表示水域。網格中的格仔水平和垂直方向相連 對角線方向不相連 整個網格被水完全包圍,但其中恰好有乙個島嶼 或者說,乙個或多個表示陸地的格仔相連組成的島嶼 島嶼中沒有 湖 湖 指水域在島嶼內部且不和島嶼周圍的水相連 格仔是邊長為 1 的正...