日常訓練 20170612 鑰匙

2021-08-02 12:11:20 字數 1963 閱讀 1359

題意簡述:

給定乙個由

n 個實數組成的序列 a1

,a2,

…,an

,你需要求出對於所有的滿足 1≤

i≤j≤

n 整數 i,

j ,∏r

i=la

i 的最大值是多少。

輸入格式:

第一行是乙個整數

n 。

第二行有

n個由空格分隔的實數 a1

,a2,

a3,…

,an−

1,an

輸出格式:

如果答案 k=

0 或者 1≤

|k|<

10 ,那麼請直接輸出答案並保留三位小數。否則,若答案用科學計數法表示為 a×

10b(其中 1≤

|a|≤

10 ,

b 是整數),你需要輸出 ae

b,其中

a 要保留三位小數。

題解:

一開始想只要取個對數就能隨便做了,但寫著寫著就感覺細節很麻煩,乘積有正有負,所以要正負分開考慮,如果答案也分正負更新會寫得很麻煩,不難發現元素不少於

2個時答案非負(可以用字首積和鴿巢原理簡單證明)。那麼我們做了字首積之後只要用前後兩個字首積同正或同負來更新了。還有一些初值細節,比如對於前後同正的字首積計算時字首積最小值可以設初值為

1 ,表示可以是原序列從第

1個元素開始的字首,但是對於前後都負的字首積計算時字首積最小值是不能簡單設初值處理,只能記錄字首積最小值存不存在,而很難設初值處理。

#include

typedef

long

double ld;

const

int n = 1e5 + 10;

const

long

double eps = 1e-7;

int n, mxf, sumf;

long

double mx, mn, sum, temp, a[n];

int main()

if (a[1] < -eps) printf("-"), a[1] = -a[1];

a[1] = log(a[1]) / log(10);

printf("%.3fe%d\n", pow(10, a[1] - floor(a[1])), (int)floor(a[1]));

return

0; }

mx = -100;

sumf = 1;

sum = 0;

mn = 0;

bool updated = 0;

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

sum += log(fabs(a[i])) / log(10);

if (a[i] < -eps) sumf *= -1;

if (sumf == -1)

}sumf = 1;

sum = 0;

mn = 0;

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

sum += log(fabs(a[i])) / log(10);

if (a[i] < -eps) sumf *= -1;

if (sumf == 1)

mx = std::max(mx, sum - mn),

mn = std::min(mn, sum);

}if (mx < 1)

printf("%.3f\n", pow(10, mx));

else

printf("%.3fe%d\n", pow(10, mx - floor(mx)), (int)floor(mx));

return

0;}

日常訓練 壓縮

巨大的文字往往令人頭疼,特別是文字內容有大量重複的情況下,巨大的文字不便於運輸和閱讀,於是我們提出了noip nonsense obivous index pattern 荒謬的顯然索引法 一種 有效的 壓縮文字的方法。noip壓縮後的格式很特別,乙個文字壓縮後由若干個單元組成,每個單元由3部分組成...

日常訓練 Tree

j 對於h u j 時間複雜度的證明也是比較經典了,每次列舉的是sz eu s zev 相當於每次從a,b 中各任選一點,它們的lc a 為 u 這樣的點對列舉不會重複,因此總的時間複雜度為o n2 include include include include include using name...

日常訓練 mod

給定 p 1,p 2,p n,b 1,b 2,b m 求滿足 x mod p 1 equiv a 1,x mod p 2 equiv a 2,x mod p n equiv a n 的 x 對 b 1,b 2,b m 取模的結果.第一行兩個整數 n,m 接下來 n 行,每行有乙個整數 a i 接下來...