20171124校內訓練

2022-08-05 01:15:13 字數 2209 閱讀 2021

把那個sigma符號看成列舉。

顯然,這個函式是單峰函式,且開口向上(自己腦補一下)

然後三分。對於把所有數減去乙個數x,如何統計此時的sum值呢?

對於乙個右端點,如何找到乙個左端點使得此時的sum值最大?

對於乙個區間[x,y],我們可以由[1,y]-[1,x-1]來得到這個區間的值。

如果我們已經知道了當前的字首最小值和最大值,即對於一段區間[1,x],我們已知區間[1,i](1<=i<=x)的最小值和最大值,我們如何算出[j,x](1<=j<=x)的最小值和最大值?

我們發現,這個值只有可能是從當前字首和-字首最小值(字首最大值)得到的。

因為減去字首最小值,會讓所得到的區間盡可能的大(即求出[j,x](1<=j<=x)的最大值)。

減去字首最大值,會讓所得到的區間盡可能的小(即求出[j,x](1<=j<=x)的最小值)。

然後就能求出答案。

每次check要初始化min(字首最小值)=0,max(字首最大值)=0,ans(sum值)=0,pre(當前字首和)=0。

把搬磚的過程建成一棵樹,根節點有所有的磚頭,然後每次分成最多三個兒子。每個葉子節點可以看成每個工地。

我們可以發現,最終的答案就是每個點的點權(工地的所需磚頭數)乘以深度的最小值。(根節點的深度為0)

我們想到了什麼?三叉huffman樹!

由於我們要讓它的深度盡量小,所以我們每個節點要盡量分3叉或者不分。

但是萬一題目給出的數是偶數呢?補乙個點權為0的節點,照常構造三叉huffman樹。(其實這棵樹不用真正的建出來,我們只需要計算答案就行了)

還有一種思考方式:考慮到分磚頭太難,我們考慮合併磚頭。則題意變為:有n堆磚頭,我們要把這些磚頭合併成一堆。每次最多合併3堆磚頭。合併的代價為你合併的磚頭總數。求最小代價。

合併果子!這就比較好做,貪心,每次合併最小3堆。可是,偶數怎麼辦呢?

偶數就意味著你最後合併完了後只剩兩堆,但這樣合併一般不優啊。所以,我們就考慮先合併最小的兩堆,然後3堆3堆的合。

至於為什麼要合併最小的兩堆,我們可以看成,這裡還有一堆0個磚頭,這樣我們就要把這三堆合併。即先合併最小的兩堆。

#include#include

#include

using

namespace

std;

long

long ans=0

;priority_queue

long,vector

long>,greater

long> >q;

intmain()

if(n==1)

if(n%2==0)

while(q.size()>1

)

printf(

"%lld

",ans);

return0;

}

view code

20161104校內訓練

一道類似模擬的題,就根據所寫的東西來做就可以了。include define rep i l r for int i l i r i define per i r l for int i r i l i define erep i u for int i head u i i e i nxt usi...

2017 4 14校內訓練

hzwer拿了幾道noi中比較簡單的給我們做 a.noi2009 植物大戰殭屍 思路 考慮最小割,如果乙個植物的權值x是正的,我們先預設吃掉它,使答案加上x並讓s向這個點連x,割這條邊相當於不吃這個植物,否則讓這個點向t連 x,割這條邊相當於吃這個植物,每個植物讓它能攻擊到的格仔和它的前一格向它連i...

2017 4 7校內訓練

喪病hzwer的ctsc訓練賽 my ac 3 4 a.ctsc2014 企鵝qq 思路 亂hash,我比較菜,寫的醜 各種wa tle,好久才a掉。include include using namespace std define ll long long define mn 200 defin...