BZOJ 2171 K凹凸序列

2021-10-04 18:56:49 字數 2866 閱讀 5224

題目描述

乙個序列的第1,3,5…項被稱作奇數項,第2,4,6…項被稱作偶數項。乙個序列a[1…n]被稱作zigzag序列當且僅當以下兩個條件中的乙個(或兩個)成立: 1)除了首項,所有的奇數項都比它的前項小且所有的偶數項都比它的前項大。 2)除了首項,所有的奇數項都比它的前項大且所有的偶數項都比它的前項小。乙個序列a[1…n]被稱作k凹凸序列當且僅當它的最長zigzag子串行(不一定是連續子串行)的長度不超過k。現在有乙個序列a[1…n],每次可以花費1的代價使得a中的某一項增加或減少1。我們的目的是花費最少的代價讓它成為k凹凸序列。輸入的第一行包含兩個正整數,分別表示數列a[1…n]的長度n和k。接下來的n行每行乙個自然整數,依次表示數列的項。

資料範圍

前1個測試點滿足:k=1,n≤20000

第2~8個測試點滿足:k=2,n≤20000

第9~15個測試點滿足:k=3,n≤20000

第16~20個測試點滿足:k≤10,n≤1000

所有測試點滿足:a[i]≤50000

首先需要理解這種子串行就是一大一小(也就是凹凸的),觀察資料範圍,不難發現本題需要資料分治。

k =1

k=1k=

1,最簡單的一種情況,把所有數都變成中位數。

k =2

k=2k=

2,整個序列必須是單調不減/

//單調不增的,就變成了這道題 k=3

k=3k=

3,一定有乙個轉折點,使得前面單調不減,後面單調不增/

//前面單調不增,後面單調不減,那麼我們就列舉轉折點,可以用k=2

k=2k=

2的方法預處理改變的花費,但由於我們要知道每個位置的花費,我們維護每個區間的和s

ss,在左偏樹上的和hshs

hs,還記錄上一次合併的花費,由絕對值的幾何意義知道這個區間新的花費是s−2

hs

s-2hs

s−2h

s,然後還要特殊考慮區間長度為奇數的情況,要出去中位數的影響(再加上乙個中位數),這一部分可以結合**理解。

k =4

k=4k=

4,發現此時n

≤1000

n\le1000

n≤1000

,用k =3

k=3k=

3的方法預處理把每個區間變成單調不增/

//單調不減的花費,然後就有乙個很顯然的dpdp

dp了,最後要求出把原序列劃分成k−1

k-1k−

1個單調段的最小花費,o(n

2k

)o(n^2k)

o(n2k)

暴力d pdp

dp不解釋。

至於**,emm

memmm

emmm

,應該還能夠接受吧,就是調得有點久,有幾個我遇到的坑點寫了注釋。

#include

#include

#include

#include

using

namespace std;

#define ll long long

const

int n =

1005

;const

int m =

20005

;int

read()

int n,m,k,ans,a[m]

,ch[m][2

],dis[m]

,rt[m]

,siz[m]

;int cost[m]

,e[m]

,s[m]

,hs[m]

,lu[m]

,ld[m]

,ru[m]

,rd[m]

;int up[n]

[n],dw[n]

[n],fu[n][15

],fd[n][15

];intmerge

(int x,

int y)

void

adjust()

}int

abs(

int x)

intwork

(int r[m]

,int x=1)

}return r[n];}

void

work1()

void

work2()

void

work3()

void

work4()

for(

int i=

1;i<=n;i++

)memset

(fu,

0x3f

,sizeof fu)

;memset

(fd,

0x3f

,sizeof fd)

; fu[0]

[0]=fd[0]

[0]=

0;for(

int i=

1;i<=n;i++

)for

(int l=

1;l<=k;l++

)for

(int j=

0;j) ans=

0x3f3f3f3f

;for

(int l=

1;l)//要注意不一定是k最優喲

//一開始寫成<=k調了好久

ans=

min(ans,

min(fu[n]

[l],fd[n]

[l]));

printf

("%d\n"

,ans);}

intmain()

BZOJ 3110, K大數查詢

傳送門 要求維護乙個數列,支援在某部分的每個位置填上乙個數以及查詢某部分第k大的數字。終於學習了一下樹套樹的姿勢 其實和自己想的也差不多 但是不學還是打不出 來 外層是權值線段樹,內層是區間線段樹。要注意的細節比較多。二分查詢過程中結果可能超過maxlongint,需要用unsigned int型別...

BZOJ1073 k短路(A 演算法)

a 演算法,也叫啟發式搜尋,就是設計乙個預估函式,然後在搜尋的過程中進行有序的搜尋,我們設到目前狀態的花費為f x 到目標狀態的估計花費為h x 那麼我們按照h x f x 排序即可,這道題裡起點到目前的距離為f x 目前到終點的最短路為g x 然後進行暴力搜尋即可。by vane includeu...

K大數查詢(bzoj 3110)

有n個位置,m個操作。操作有兩種,每次操作如果是1 a b c的形式表示在第a個位置到第b個位置,每個位置加入乙個數c 如果是2 a b c形式,表示詢問從第a個位置到第b個位置,第c大的數是多少。第一行n,m 接下來m行,每行形如1 a b c或2 a b c 輸出每個詢問的結果 2 51 1 2...