bzoj4385 Wilcze do y 單調佇列

2021-07-10 06:26:09 字數 931 閱讀 3193

(趕腳poi要被許可權。。趕緊趁現在刷幾道水題)。

首先令s[i]表示(1,i)序列的和。現在考慮一段序列(i,j),如何判斷這段序列是否滿足條件呢?當j-i+1<=d時顯然滿足;否則,我們肯定是要讓這一段序列中總和最大的一段(x,x+d)變為0,換句話說,如果設x,使x滿足i<=x,x+d<=j且s[x+d]-s[x]值最大,那麼如果s[i]-s[j-1]-(s[x+d]-s[x])<=p,那麼(i,j)滿足條件。

因此我們列舉右端點j,顯然i隨著j的增大而增大,x也隨之增大。因此我們用單調佇列維護此時(i,j)的x,然後如果s[i]-s[j-1]-(s[x+d]-s[x])>p就不斷i++,第乙個滿足條件的i就是當右端點為j時左端點的最大延伸長度。

時間複雜度o(n)。

ac**如下(實現與上述描述有所不同):

#include#include#include#define ll long long

using namespace std;

int n,d,q[2000005]; ll s[2000005],p;

ll read()

return x;

}int main(){

scanf("%d%lld%d",&n,&p,&d); int i;

for (i=1; i<=n; i++) s[i]=s[i-1]+read();

int ans=d,head=1,tail=0,j=0;

for (i=d; i<=n; i++){

while (head<=tail && s[i]-s[i-d]>s[q[tail]]-s[q[tail]-d]) tail--;

q[++tail]=i;

while (s[i]-s[j]-s[q[head]]+s[q[head]-d]>p){

j++; if (q[head]-d

by lych

2016.3.3

NKOJ 4385 簡單計算(矩陣乘法)

問題描述 給你三個整數 n,x,和 m,計算 n k 1k xxk 輸入格式 一行,三個整數n,x,和 m,輸出格式 一行,乙個整數,表示計算結果 樣例輸入 1 100 1 10000 樣例輸出 1 樣例輸入 2 3 4 1000 樣例輸出 2 提示 1 n,m 2 10 9 1 x 50.注意到x...

BZOJ1052 BZOJ3760 覆蓋問題

原題位址 先說自己的逗比方法 二分答案,把所有點用乙個最小的矩形 框 起來,易證矩形的其中乙個端點是最優解中正方形的乙個端點,然後列舉四個端點後遞迴處理,差不多了 然後 olz黃學長的o n 做法 ac code include include include using namespace std...

動態點分治 bzoj 3730,bzoj 1095

總結一下動態點分治的模板。對於乙個樹,把它點分的同時記錄每個點的所有父親 logn個 並記錄點距其父親的距離。具體實現就是dfs的時候fa x dep x u,dis x dep x d bzoj1095 您需要寫乙個程式支援反轉點的顏色,求距離最遠的黑色點對的距離。解析 在每個點u存乙個堆st記錄...