一本通1598【 例 2】最大连续和
1598:【 例 2】最大连续和
时间限制: 1000 ms 内存限制: 524288 KB【题目描述】
给你一个长度为 n 的整数序列 {A1,A2,⋯,An},要求从中找出一段连续的长度不超过 m 的子序列,使得这个序列的和最大。
【输入】
第一行为两个整数 n,m;
第二行为 n 个用空格分开的整数序列,每个数的绝对值都小于 1000。
【输出】
仅一个整数,表示连续长度不超过 m 的最大子序列和。
【输入样例】
6 4 1 -3 5 1 -2 3
【输出样例】
7
【提示】
数据范围与提示:
对于 50% 的数据,1≤N,M≤104;
对于 100% 的数据,1≤N,M≤2×105 。
sol:就像模板一样,维护前缀和,对于每一个前缀和S[i],寻找S[i-m]~S[i-1]中最小的那个,用单调队列维护即可
#include <bits/stdc++.h> using namespace std; typedef int ll; inline ll read() { ll s=0; bool f=0; char ch=' '; while(!isdigit(ch)) { f|=(ch=='-'); ch=getchar(); } while(isdigit(ch)) { s=(s<<3)+(s<<1)+(ch^48); ch=getchar(); } return (f)?(-s):(s); } #define R(x) x=read() inline void write(ll x) { if(x<0) { putchar('-'); x=-x; } if(x<10) { putchar(x+'0'); return; } write(x/10); putchar((x%10)+'0'); return; } inline void writeln(ll x) { write(x); putchar('\n'); return; } #define W(x) write(x),putchar(' ') #define Wl(x) writeln(x) const int N=200005,inf=0x3f3f3f3f; int n,m,Qzh[N]; struct Record { int Shuz,Weiz; }Ddq[N]; int main() { // freopen("sum12.in","r",stdin); int i,Head=0,Tail=0,ans=-inf; R(n); R(m); for(i=1;i<=n;i++) { int x=read(); Qzh[i]=Qzh[i-1]+x; while(Head<Tail&&Ddq[Head].Weiz<i-m) Head++; ans=max(ans,Qzh[i]-Ddq[Head].Shuz); while(Head<=Tail&&Qzh[i]<=Ddq[Tail].Shuz) Tail--; Ddq[++Tail]=(Record){Qzh[i],i}; } Wl(ans); return 0; } /* input 5 2 -21 -2 -1 -11 -3 output -1 */
河田は河田、赤木は赤木……。
私は誰ですか。教えてください、私は誰ですか。
そうだ、俺はあきらめない男、三井寿だ!