6029 雅禮集訓 2017 Day1 市場

2021-08-09 08:47:12 字數 3755 閱讀 7276

#6029. 「雅禮集訓 2017 day1」市場

題目描述

從前有乙個**市場,在一位執政官到來之前都是非常繁榮的,自從他來了之後,發布了一系列奇怪的政令,導致**市場的衰落。

有 n nn 個商販,從 0∼n−1 0 \sim n - 10∼n−1 編號,每個商販的商品有乙個** ai a_ia​i​​,有兩種政令:

l,r,c l, r, cl,r,c,對於 i∈[l,r],ai←ai+c i \in [l, r], a_i \leftarrow a_i + ci∈[l,r],a​i​​←a​i​​+c

l,r,d l, r, dl,r,d,對於 i∈[l,r],ai←⌊ai/d⌋ i \in [l, r], a_i \leftarrow \lfloor / \rfloori∈[l,r],a​i​​←⌊a​i​​/d⌋

現在有乙個外鄉的旅客想要了解**市場的資訊,有兩種詢問方式:

給定 l,r l, rl,r,求 mini∈[l,r]ai \min_ a_imin​i∈[l,r]​​a​i​​

給定 l,r l, rl,r,求 ∑i∈[l,r]ai \sum_ a_i∑​i∈[l,r]​​a​i​​

輸入格式

第一行為兩個空格隔開的整數 n,q n, qn,q 分別表示商販個數和政令 + 詢問個數。

第二行包含 n nn 個由空格隔開的整數 a0∼an−1 a_0 \sim a_a​0​​∼a​n−1​​

接下來 q qq 行,每行表示乙個操作,第乙個數表示操作編號 1∼4 1 \sim 41∼4,接下來的輸入和問題描述一致。

輸出格式

對於每個 3、4 操作,輸出詢問答案。

樣例樣例輸入

10 10

-5 -4 -3 -2 -1 0 1 2 3 4

1 0 4 1

1 5 9 1

2 0 9 3

3 0 9

4 0 9

3 0 1

4 2 3

3 4 5

4 6 7

3 8 9

樣例輸出

-2

-2-2-20

11

資料範圍與提示

對於 30% 30\%30% 的資料,n,q≤103 n, q \leq 10 ^ 3n,q≤10​3​​;

對於 60% 60\%60% 的資料,保證資料隨機;

對於 100% 100\%100% 的資料,1≤n,q≤10^5,0≤l≤r≤n−1,ci∈[−10^4,10^4],d∈[2,10^9] 

線段樹裸題 

一開始沒想到怎麼處理區間除 

區間除就是把它轉化成區間減 

需要減去的數肯定不同

但是可以考慮到一點就是如果某一段需要減去的數字是一樣的

那就可以用區間更新的方法更新這一段

從而對整段[l,r]進行更新

所以對於某一段[l,r] 判斷這一段是否可以減去同乙個數字的方法就是看這一段區間的最大值max和最小值min需要減去多少

如果max和min需要減去的數字是一樣大的

那麼說明這一段都可以減去這個數字

標記下放也要把最大最小值更新 

1 #include 2 #include 3

4 typedef long

long

ll;5

6const

int maxn=100010;7

8int

n,m;910

struct

segmenttree ;

15 segmenttree t[maxn<<2

];16

17 inline void read(int&x)

2324 inline ll min(ll a,ll b)

2526 inline ll max(ll a,ll b)

2728

void build_tree(int now,int l,int

r) 36

int mid=(l+r)>>1

;37 build_tree(now<<1

,l,mid);

38 build_tree(now<<1|1,mid+1

,r);

39 t[now].mn=min(t[now<<1].mn,t[now<<1|1

].mn);

40 t[now].mx=max(t[now<<1].mx,t[now<<1|1

].mx);

41 t[now].sum=t[now<<1].sum+t[now<<1|1

].sum;42}

4344 inline void down(int

now)

5354

void tree_add(int now,int l,int r,int

v) 61

if(t[now].tag) down(now);

62int mid=(t[now].l+t[now].r)>>1;63

if(l<=mid) tree_add(now<<1

,l,r,v);

64if(r>mid) tree_add(now<<1|1

,l,r,v);

65 t[now].mn=min(t[now<<1].mn,t[now<<1|1

].mn);

66 t[now].mx=max(t[now<<1].mx,t[now<<1|1

].mx);

67 t[now].sum=t[now<<1].sum+t[now<<1|1

].sum;68}

6970

void tree_div(int now,int l,int r,int

v) 82}83

if(t[now].tag) down(now);

84int mid=(t[now].l+t[now].r)>>1;85

if(l<=mid) tree_div(now<<1

,l,r,v);

86if(r>mid) tree_div(now<<1|1

,l,r,v);

87 t[now].mn=min(t[now<<1].mn,t[now<<1|1

].mn);

88 t[now].mx=max(t[now<<1].mx,t[now<<1|1

].mx);

89 t[now].sum=t[now<<1].sum+t[now<<1|1

].sum;

90}

9192 ll query_min(int now,int l,int

r) 101

102 ll query_sum(int now,int l,int

r) 111

112int

hh()

123else

if(type==2

) 127

else

if(type==3) printf("

%lld\n

",query_min(1

,x,y));

128else printf("

%lld\n

",query_sum(1

,x,y));

129}

130return0;

131}

132133

int sb=hh();

134int main(int argc,char**argv)

**

雅禮集訓 2017 價

傳送門 乙個不太顯然的最小割做法。我們這麼連邊 源點向藥物連 infty p i 容量的邊,藥物向它對應的藥材連 infty 容量的邊,藥材向匯點連 infty 容量的邊。用源點的流量減去最小割,再負回來就可以求出答案了。怎麼理解呢?割掉一條邊表示不選其對應的藥物或藥材,我們發現最後的方案一定是完美...

雅禮集訓 2017 Day5 珠寶

題目描述 miranda 準備去市裡最有名的珠寶展覽會,展覽會有可以購買珠寶,但可惜的是只能現金支付,miranda 十分糾結究竟要帶多少的現金,假如現金帶多了,就會比較危險,假如帶少了,看到想買的右買不到。展覽中總共有 n種珠寶,每種珠寶都只有乙個,對於第 i種珠寶,它的售價為 ci 萬元,對 m...

雅禮集訓 2017 Day2 解題報告

我怎麼知道這種題目都能構造樹形結構。根據高度構造一棵樹,在樹上倍增找到最大的小於約束條件高度的隔板,開乙個 vector 記錄一下,然後對於每個 vector 按照高度排序一下,樹形 dp 即可 code below include define pii pair define mp make pa...