bzoj 4631 踩氣球 線段樹合併

2022-04-30 08:27:12 字數 2627 閱讀 5296

time limit: 10 sec  memory limit: 256 mb

submit: 265  solved: 136

[submit][status][discuss]六一兒童節到了, shuxk 被迫陪著m個熊孩子玩乙個無聊的遊戲:有n個盒子從左到右排成一排,第i個盒子裡裝著ai個氣球。

shuxk 要進行q次操作,每次從某乙個盒子裡拿出乙個沒被踩爆的氣球,然後熊孩子們就會立刻把它踩爆。

這m個熊孩子每個人都指定了乙個盒子區間[li, ri]。 如果某乙個時刻,乙個熊孩子發現自己選定的盒子區間[li, ri]中的所

有氣球都已經被踩爆了,他就會非常高興(顯然之後他一直會很高興)。

為了不辜負將自己的任務強行塞給 shuxk 的那個人的期望, shuxk 想向你詢問: 

他每次操作過後會有多少個熊孩子很高興。

第一行包含兩個正整數n和m,分別表示盒子和熊孩子的個數。

第二行包含n個正整數ai( 1 < = ai < = 10^5),表示每個盒子裡氣球的數量。

以下m行每行包含兩個正整數li, ri( 1 < = li < = ri < = n),分別表示每乙個熊孩子指定的區間。

以下一行包含乙個正整數q,表示 shuxk 操作的次數。

以下q行每行包含乙個正整數x,表示這次操作是從第x個盒子裡拿氣球。為

假設輸入的正整數是x',那麼真正的x = (x' + lastans − 1)mod n + 1。其

中lastans為上一次詢問的答案。對於第乙個詢問, lastans = 0。

輸入資料保證1 < = x' < = 10^9, 且第x個盒子中有尚未被踩爆的氣球。

n < = 10^5 ,m < = 10^5 ,q < = 10^5

包含q行,每行輸出乙個整數,表示 shuxk 一次操作後詢問的

答案。答案的順序應與輸入資料的順序保持一致。

5 31 1 1 1 1

5 52 2

1 35

4 2

5 2 30

1 1 2 3

【樣例說明】

實際上每次操作的盒子是: 4 2 1 3 5

在第二次操作後,第二個熊孩子會高興 (區間[2,2]中的氣球已經全部被踩爆)。

在第四次操作後,第三個熊孩子會高興(區間[1,3]中的氣球已經全部被踩爆)。

在第五次操作後,第乙個熊孩子會高興(區間[5,5]中的氣球已經全部被踩爆)。

這題好像怎麼做都行,於是我寫了一發線段樹合併。

維護n棵權值線段樹,把每個區間以左端點為值插入右端點代表的線段樹中。

再用個並查集維護每個點前第乙個沒被踩完的盒子$f[i]$。

每次踩空乙個盒子i,找到$f[i]$,把$i$這棵線段樹中大於$f[i]$的點刪掉,再把$i$合併到$f[i]$上。

1 #include2 #include3 #include4 #include5

#define n 100005

6using

namespace

std;

7int

n,m;

8int

c[n],now;

9struct

node

10a[n*20];int

cnt;

13void add(int x,int l,int r,int

z)14

20int mid=(l+r)>>1;21

if(z<=mid)

2226

else

2731 a[x].sum=a[a[x].l].sum+a[a[x].r].sum;

32return;33

}34intf[n];

35int find(int

x)36

40int la=0;41

introot[n];

42void del(int x,int l,int r,int

z)43

50int mid=(l+r)>>1;51

if(z<=mid)

5255

if(a[a[x].r].sum)del(a[x].r,mid+1

,r,z);

56 a[x].sum=a[a[x].l].sum+a[a[x].r].sum;

57return;58

}59void merge(int x,int y,int l,int

r)60

66int mid=(l+r)>>1;67

if(a[x].l)

6871

else a[x].l=a[y].l;

72if

(a[x].r)

7376

else a[x].r=a[y].r;

77 a[x].sum=a[a[x].r].sum+a[a[x].l].sum;

78return;79

}80intmain()

8192

int q;scanf("

%d",&q);

9394

for(int i=1;i<=q;i++)

95106 printf("

%d\n

",la);

107}

108return0;

109 }

463 島嶼的周長

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

463 島嶼的周長

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

463 島嶼的周長

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