(趕腳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記錄...