蒟蒻養成記 構造數列(2)

2021-07-31 16:42:10 字數 2098 閱讀 7700

ograda

【題目描述】

智慧型有乙個數列a,帆帆也有乙個數列b,每個數列都有n個數字

對於乙個數列,裡面的數字都是不同的。

帆帆覺得智慧型的數列比較好看,打算重排數列b,他想把自己的數列弄得盡量和智慧型的數列相似,我們定義相似為b中相鄰數字的大小關係和a中相鄰數字的大小關係一致。

比如說a=,其中a1不過帆帆想同時讓自己的數列最好看,我們定義好看程度為|b1-b2|+|b2-b3|+....+|bn-1-bn|,帆帆希望好看程度盡量大。

ps.如果對題目還不理解請分析樣例

帆帆因為要去和萌華領證(當然不是結婚證,是去台灣的簽證),所以把這個問題交個了東東,但是東東很笨,他需要你的幫助。

【輸入描述】

第一行:n(2<=n<=300 000)

第二行:智慧型的數列

第三行:帆帆的n個數

【輸出描述】

第一行:好看程度

第二行:重排後的帆帆的數列

【輸入輸出描述】

input

5 7 4 9

1 2 3 4

output

2 4 1 3

樣例解釋:

帆帆有以下幾種重排的方法:

好看程度:2+1+2=6

好看程度:3+2+1=6

好看程度:1+2+3=6

好看程度:2+3+2=7

好看程度:1+3+1=5

input

9 5 1 2 6 7 4 18 2012

10 40 20 30 50 7080 100 1000 500

output

100 80 10 40 501000 20 70 500 30

【解法】

首先,暴力可以過部分點。但在社會主義建設的今天,一定要堅持ac的原則(我在講什麼)

然後想到,其實第乙個陣列有用的只是大小關係。於是可以定義對於a【i】和a【i+1】,只要確定大小關係。

於是樣例一可以變成:<><

然後對b陣列(第二個數列)快排,從左往右,依次在 < > 中間加入最大值,然後刪去這個最大值(避免重複),在 > < 中間加入最小值,然後刪去這個最小值,後面只需要在剩下的陣列中找最大最小值(可以用兩個指標l,r在陣列中從兩邊往中間靠來實現)

接下來處理開頭結尾,開頭和結尾都放最大最小值(看開頭和第二個,最後乙個和倒數第二個的關係決定)

剩下的根據和下乙個數的關係來從左往右填數,因為填什麼不影響大小關係

證明:因為所填區域為單調 ,所以 |a-b|+|b-c|+....+|y-z|=a-z或z-a

所以可以直接填

【**】

#include

#include

#include

#include

#include

#include

using namespace std;

int a[300001];

int b[300001];

int c[300001];

int i,j,k,m,n,o,p,js,z,y;

long long ll;

int main()

if((a[i-1]

}//***********************************====

if(a[1]

else

if(a[n]

else

//***********************************====

for(int i=2;i<=n-1;i++)

if(a[i]       

}}//***********************************====

for(int i=2;i<=n;i++)ll=ll+abs(c[i]-c[i-1]);

fprintf(fout,"%i64d\n",ll);

for(int i=1;i<=n;i++)fprintf(fout,"%d ",c[i]);

fclose(fin);

fclose(fout);

}

蒟蒻養成記 構造數列

題目描述 你需要求乙個n個不同數字的序列p,p i 是1 n 中的數,且滿足對於 1 i n,p p i n i 1 輸入格式 乙個數字n 1 n 10 5 輸出格式 輸出n個數字序列 p,任意輸出一組答案即可 輸入輸出樣例 input1 1output1 1input2 2output2 1inp...

bzoj4363 蒟蒻的數列

description 蒟蒻dcrusher不僅喜歡玩撲克,還喜歡研究數列 題目描述 dcrusher有乙個數列,初始值均為0,他進行n次操作,每次將數列 a,b 這個區間中所有比k小的數改為k,他想知 道n次操作後數列中所有元素的和。他還要玩其他遊戲,所以這個問題留給你解決。input 第一行乙個...

BZOJ 4636 蒟蒻的數列

bzoj 4636 蒟蒻的數列 線段樹 動態開點 蒟蒻dcrusher不僅喜歡玩撲克,還喜歡研究數列 題目描述 dcrusher有乙個數列,初始值均為0,他進行n次操作,每次將數列 a,b 這個區間中所有比k小的數改為k,他想知 道n次操作後數列中所有元素的和。他還要玩其他遊戲,所以這個問題留給你解...