AT2005 單調棧,差分

2021-10-16 08:59:43 字數 2314 閱讀 7779

傳送門

分析整個操作過程是什麼特點。如果之後有乙個長度比之前最短的還要短,那麼後面的統統截掉,相當於白給,所以,任何降序的操作都是無意義的。所以先利用單調棧處理出乙個嚴格單調上公升的序列(注意n

nn也要放進去,因為n

nn是初始長度)。

面對乙個單調上公升的序列,需要乙個方法來處理答案。考慮從長度為a→b

a\to b

a→b,則必定是長度為a

aa時的若干個迴圈加上乙個a

aa的字首構成長度為bbb。

而這樣的兩個部分可以看成是從b

bb拆開來的,乙個是a

aa的 ⌊ba

⌋\left\lfloor\frac\right\rfloor

⌊ab​

⌋倍,乙個是b%a

b\%a

b%a的一倍。就可以轉化為兩個子問題遞迴,直到序列中找不到比當前要處理的數小的數為止。如圖,假設我想計算黑色長度變成紅色長度,怎麼做?

那麼,就是在黑色長度複製幾段到剩餘的小於黑色長度為止,即如圖框內。那麼也就是4

44次的黑色長度加上方框長度即所求的,然後繼續向小的遞迴即可。每次都記錄當前這段的權值也就是計算次數即可。

最後答案上區間加的時候差分一下即可。這就是大體的思路,具體細節看注釋。

對於t le

tletl

e,深有感觸。(屬於個人腦抽,不喜勿噴,可跳過)

我在主函式裡就放了乙個函式,直接從最大的那個開始分,然後每次分兩個解決。結果是,同乙個數可能在搜尋樹上出現多次,導致無意義的多算,參考了別人的acac

ac**後,發現對於每乙個數都只需要把它的餘數進行遞迴處理即可,本身只要將權值加到下乙個就可以了,然後加了乙個t

tt才過的。

反思:這是乙份tle

\color

tle的**。

#include

#define ll long long

using

namespace std;

ll read()

while

(ch>=

'0'&&ch<=

'9')

return w*f;

}const

int maxn=

1e5+10;

ll q,ans[maxn]

,st[maxn]

,tim[maxn]

;int n,q,m,cnt=0;

ll find

(ll x)

return ans;

}//查詢比x小的最大的數

void

solve

(ll x,ll t)

//如果小到連最小的數都無法歸約了,就可以直接加在序列上。

//簡言之,就是乙個序列就可以包含的,肯定不會造成更多的影響

int id=

find

(x);

// cerr

+=x/st[id]

*t;//在找到的這個數中加入次數

solve

(x%st[id]

,t);

//繼續遞迴求解

}//表示解決t次的長度為x的函式

intmain()

// for(int i=1;i<=cnt;i++) cerr

;//最大的只要1次

for(

int i=cnt;i>=

2;i--

) tim[i-1]

+=st[i]

/st[i-1]

*tim[i]

,//向下乙個傳遞次數

solve

(st[i]

%st[i-1]

,tim[i]);

//遞迴解決餘數,看是否可以 歸約到更小的序列中的數解決

solve

(st[1]

,tim[1]

);//最後解決最小的數

for(

int i=

1;i<=n;i++

) ans[i]

+=ans[i-1]

;//差分還原

for(

int i=

1;i<=n;i++

)printf

("%lld\n"

,ans[i]);

}

思路顯亂,望包含。

二分 單調棧 SPOJ MINSUB

題目 一開始並不會做,然後看了看下面的題解 然後大體思想理解了,之前寫單調棧一直都是用stack,node裡記錄向前延伸向後延伸以及當前的數值和位置,寫這個題的時候覺得用這種方法寫起來比較麻煩,然後嘗試去使用題解中的方法,單調棧可以像這篇題解中使用乙個陣列來模擬棧,同時分兩次遍歷陣列並統計每個元素的...

week5作業 單調棧 差分與字首和 尺取法

給定乙個直方圖,求直方圖中可連成的最大矩形面積 問題核心 單調遞增棧 利用單調遞增棧維護各個下標 左端點下標,利用各個高度判斷大小關係 面積 下標之差 高度 注意資料範圍,本題需使用long long include include using namespace std const int max...

10 29 T1 max 單調棧 貢獻法 二階差分

對於每個i用單調棧求出小於i的第乙個比他大的數l i 以及大於i的第乙個比他大的數r i i一定是l i r i 中最大的數,1 a 1分別加 1 a 1 a i a 2 b 1加 a 1 a i a 2 a b 1 遞減加 用二階差分o 1 完成修改 用兩遍字首和求出答案 include incl...