洛谷 Daniel13265 的公開賽 A 替換

2021-10-04 19:20:21 字數 4347 閱讀 8544

時間限制:1.00s | 記憶體限制:125.00mb

題目背景

替換永遠比刪除更徹底。

題目描述

daniel13265 有一串由各種漂亮的貝殼組成的項鍊,但由於各種原因,這個項鍊不是環形的,而僅僅是用一根普通的絲線串起來的。項鍊上的每個貝殼都有乙個好看程度 ai,相同種類的貝殼有著相同的好看程度,而不同種類的貝殼有著不同的好看程度。

danie13265 定義, 第 l 個至第 r 個這一段貝殼是對稱的,當且僅當

∑ i=

lr(a

i−al

+r−i

)2=0

\sum_^r(a_i-a_)^2=0

i=l∑r​

(ai​

−al+

r−i​

)2=0

daniel13265 經常從中取出一段貝殼。如果這一段貝殼是對稱的,他就會非常高興;如果這一段貝殼不是對稱的,那麼他會將其中的某些貝殼替換成新的,以使得這一段貝殼成為對稱的。一次替換可以任意地改變任何乙個位置上貝殼的好看程度,但是過多的替換會使這一段貝殼脫離原本的模樣,所以 daniel13265 至多會進行 k 次替換。如果一段貝殼在進行至多 k 次替換後能夠成為對稱的,那麼 daniel13265 就稱這一段貝殼是「可觀賞的」。

daniel13265 簡單地將第 l 個至第 r 個這一「可觀賞的」的貝殼段的「觀賞指數」定義為

∏ i=

lrai

\prod_^r a_i

i=l∏r​

ai​其中 ai 表示第 i 個貝殼原本的好看程度

他現在很好奇,在這個貝殼組成的項鍊中,「可觀賞的」貝殼段中「觀賞指數」的最大值。但是由於這個值可能很大,所以你只需要求出它對 109+7 取模後的結果即可。

輸入格式

輸入共 2 行。

第一行兩個正整數 n,k,表示這個貝殼組成的項鍊中貝殼的數目與 daniel13265 對一段貝殼最多進行替換的次數。

第二行 n 個用單個空格隔開的正整數,第 i 個數 ai表示項鍊上第 i 個貝殼的好看程度。

輸出格式
輸出一行乙個非負整數,表示「可觀賞的」貝殼段中「觀賞指數」的最大值對 109+7 取模後的結果。

輸入輸出樣例

輸入#1

7 1

1 2 4 2 3 3 4

輸出#1
輸入#2
6 1

3 1 2 250000002 1 2

輸出#2
說明/提示

樣例解釋#1

「可觀賞的」貝殼段有 [1],[2],[3],[4],[1,2],[2,3],[2,4],[3,3],[3,4],[4,2],[1,2,4],[2,3,3],[2,4,2],[3,3,4],[4,2,3],[2,3,3,4],[4,2,3,3,4],其中「觀賞指數」最大的貝殼段為 [4,2,3,3,4]。

樣例解釋#2
「可觀賞的」的貝殼段中「觀賞指數」最大的為 [2,250000002,1,2],其值為 109+8,對 109+7 取模後結果為 1。

資料範圍
對於 100% 的資料,滿足 1 ≤ n ≤ 1000,0 ≤ k ≤ n,1 ≤ ai ≤ 109+7

題意簡析

這道題,作為a題,題幹著實有點恐怖,簡直成了數學小作文閱讀理解,剛開始就勸退好多人(包括我)

(後來題面看了一輪,又回來了… )

咳咳,那麼這個題幹到底講了啥呢。in short:(寫到這裡突然尬住,到底講啥了呢(撓頭) )

①有一串由貝殼組成的項鍊(非環),每個貝殼有乙個「好看程度」,ai

②定義,l 至 r 段貝殼是對稱的,當且僅當(上面那個和式成立)

我們小學二年級就學過:若平方項的和為0,則每一平方項均為0

即,ai==al+r-i,而 i 從 l 開始遞增,也就是說 l~r 段關於中軸對稱(物理上的對稱)

③一次替換可以改變任意貝殼的「好看程度」,假如一段貝殼經過 k 次替換後,是對稱的,

則稱 l~r 這一段貝殼為「可觀賞的」(有種機翻的趕腳? )

④定義一段「可觀賞的」貝殼的「觀賞指數」為這一段貝殼「好看程度」的連乘積(上式)

⑤求表示「可觀賞的」貝殼段中「觀賞指數」的最大值對 109+7 取模後的結果

注意:求「觀賞指數」時的ai是原本的ai,而非替換後的ai

實際上並未真正替換

注意:最大值的取模,而非取模的最大值

假·分析

這題寫著好累啊(咋這麼多字)

首先,乍一看雖然有點複雜,但好在n不是很大,思路也挺簡單:

雙重for迴圈,外層列舉區間長度len,內層列舉區間左端點 l,計算該區間是否能在k次替換內成為對稱的

如果能,則計算連乘積,並與最大值做取捨,複雜度o(n2),還是可以承受的。

然後你就會看到乙個又大又紅的wa(wa地一聲哭出來)

真·分析

「醉翁之意不在酒」啊,這出題人是真的黑

那麼一大坨題幹根本就不是重點,主要問題是這個資料範圍(1 ≤ ai ≤ 109+7)(1 ≤ n ≤ 1000)

要命了這可是連乘積啊,(109+7)1000,打個折109000,這可真是,玉皇大帝來了都沒轍

想啥呢,乘起來?桃子

所以作者說要模上109+7,但卻是先求最大值再取模,先取模會改變大小關係

也就是說,擺在我們面前的問題是:如何在不求值的情況下,比較兩個連乘積的大小

而且最大值無法用特定值表示,改用區間形式(int l, r)

此時,有兩種辦法:

①取對數

log10(a*b*…*z)==log10(a)+log10(b)+…+log10(z)

這時,109000 便轉化為9000,用double比較大小不在話下。

但是,有乙個問題,log10()函式計算效率不盡如人意,如果每次直接計算,勢必超時(血的教訓)

此時我們可以發現,計算存在冗餘,可以採用預處理出對數陣列的方式解決

②兩個連乘積中的每一項相除,拆分比較

例:a=a*b*c

b=d*e*f*g*h

t=(a/d)*(b*e)*(c/f)

while(t>=1)t/=g;…t/=h;

if(t>1)a>b;

實質上是比較a/b,做商,拆項可以防止溢位

兩種方法都是o(n)地掃瞄陣列,但除法比log更快,所以可以直接計算,無需預處理(這還真不好預處理),開了o2優化後時間大概在700ms左右,卡得死死的。不開就炸了。

當然我覺得第一種更好(200ms),(第二種是比賽時我的暴力美學…先寫上再說)

這裡採用取對數的方法(賽後補的一發)(更短一些)

"talk is cheap. show me the code."

#include

#include

typedef

long

long ll;

const

int maxn =

1e3+5;

const

int mod =

1e9+7;

int a[maxn]

;double log[maxn]

;struct node

;int

main

(void);

for(

int len =

1; len <= n; len++

)for

(int i =

1; i <= n - len +

1; i++)if

(cnt <= k);}

} ll res =1;

for(

int i = max.l; i <= max.r; i++

) res *

= a[i]

, res %

= mod;

printf

("%lld\n"

, res % mod)

;return0;

}

4 5 Daniel13265 的公開賽

4.5 daniel13265 的公開賽 題目鏈結 官方題解 戳這裡居然沒有官方 暴力做法 分奇偶形式的對稱數列,1e3資料 n2搞定,但是wa了 不知道為啥qwq include include include const int mod 1e9 7 using namespace std int...

洛谷大佬改編的

很久很久以前 演算法突然出現 帶來導論 帶走了智商又消失不見 程式設計十分危險 世間誰最勇敢 一位懵逼兒趕來 大聲喊 我要寫出最高的樹 打出最大的表 搜進最深的遞迴 把ac帶回到面前 老師非常高興 忙問他的技能 年輕人想了想 他說 老師我會 非確定性有窮狀態決策自動機 再來一次 非確定性有窮狀態決策...

題解 洛谷P1738 洛谷的資料夾

一 目錄概覽 二 題目大意 三 大致思路 四 實現 五 剖析 六 總結回顧 kkksc03想好了很多應該有的資料夾路徑名。問題是,需要是使這些資料夾都存在,需要新建幾個資料夾呢?資料夾路徑是什麼?例如 a b c,表示在根目錄下有a資料夾,在a資料夾裡有b資料夾,在b資料夾裡有c資料夾。其他路徑同理...