P2073 送花(權值線段樹)

2021-10-08 20:00:09 字數 2349 閱讀 2021

題目描述

小明準備給小紅送一束花,以表達他對小紅的愛意。他在花店看中了一些花,準備用它們包成花束。

這些花都很漂亮,每朵花有乙個美麗值w,**為c。

小明一開始有乙個空的花束,他不斷地向裡面新增花。他有以下幾種操作:

操作 含義

1 w c 新增一朵美麗值為w,**為c的花。

3 小明覺得當前花束中最便宜的一朵花太廉價,不適合送給小紅,所以刪除最便宜的一朵花。

2 小明覺得當前花束中最貴的一朵花太貴,他心疼自己的錢,所以刪除最貴的一朵花。

-1 完成新增與刪除,開始包裝花束

若刪除操作時沒有花,則跳過刪除操作。

如果加入的花朵**已經與花束中已有花朵**重複,則這一朵花不能加入花束。

請你幫小明寫乙個程式,計算出開始包裝花束時,花束中所有花的美麗值的總和,以及小明需要為花束付出的總**。

輸入格式

若干行,每行乙個操作,以-1結束。

輸出格式

一行,兩個空格隔開的正整數表示開始包裝花束時,花束中所有花的美麗值的總和。以及小明需要為花束付出的總**。

樣例

輸入

1 1 1

1 2 5

21 3 3

31 5 2

-1輸出

8 5

說明/提示

對於20%資料,運算元<=100,1<=w,c<=1000。

對於全部資料,運算元<=100000,1<=w,c<=1000000。

題目分析

這道題我們可以以**為區間來維護乙個權值線段樹,權值線段樹的節點中包含美麗值的區間和、**的區間和。

操作有四種:

1:向線段樹中加入一朵美麗值為w,**為c的花。用update函式,將這朵花直接放入即可。

2/3:刪除最貴/最便宜的花。因為權值線段樹是根據**的大小放入不同的位置,因此我們進行刪除操作時不能用update函式了,要重新寫乙個remove函式來完成操作。

-1:輸出總的美麗值和**。即為tr[1]中所包含的資訊,直接輸出即可。

**如下

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#include

#define ll long long

#define pii pair

using

namespace std;

const

int n=

1e6+5;

struct nodetr[n*4]

;void

pushup

(int u)

void

update

(int u,

int l,

int r,

int x,

int v)

//插入一朵**為x,美麗值為v的花

else

}void

remove

(int u,

int l,

int r,

int s)

//刪除一朵花

;//找到該點則刪除資訊

else

else

//s=0刪除最小值

pushup

(u);

//更新父節點資訊}}

intmain()

else

if(tr[1]

.p==0)

continue

;//如果花束為空則跳過該刪除操作

else

if(op==2)

remove(1

,1,1e6,1

);else

remove(1

,1,1e6,0

);}printf

("%d %d\n"

,tr[1]

.w,tr[1]

.p);

return0;

}

洛谷 P2073 送花(權值線段樹)

這個題如果要用線段樹的話首先要考慮如何建樹,那一定是動態開點了而且要維護最大值最小值,但是最氣人的是有刪點操作,所以在新增的時候要判斷是否有節點為空。最後還有乙個條件,相同的 還不允許重新加入,看到這裡應該要換思路了既然滿足不重複的條件,想到之前有道 multiset 的題,題目用權值線段樹解決 刪...

洛谷P2073 送花

小明準備給小紅送一束花,以表達他對小紅的愛意。他在花店看中了一些花,準備用它們包成花束。這些花都很漂亮,每朵花有乙個美麗值w,為c。小明一開始有乙個空的花束,他不斷地向裡面新增花。他有以下幾種操作 操作 含義 1 w c 新增一朵美麗值為w,為c的花。3 小明覺得當前花束中最便宜的一朵花太廉價,不適...

洛谷P2073 送花

小明準備給小紅送一束花,以表達他對小紅的愛意。他在花店看中了一些花,準備用它們包成花束。這些花都很漂亮,每朵花有乙個美麗值w,為c。小明一開始有乙個空的花束,他不斷地向裡面新增花。他有以下幾種操作 操作 含義 1 w c 新增一朵美麗值為w,為c的花。3 小明覺得當前花束中最便宜的一朵花太廉價,不適...