From easthong☆holiday 描述 Description 经过几个月辛勤的工作,FJ决定让奶牛放假。假期可以在1…N天内任意选择一段(需要连续),每一天都有一个享受指数W。但是奶牛的要求非常苛刻,假期不能短于P天,否则奶牛不能得到足够的休息;假期也不能超过Q天,否则奶牛会玩的腻烦。FJ想知道奶牛们能获得的最大享受指数。 输入格式 Input Format 第一行:N,P,Q. 第二行:N个数字,中间用一个空格隔开。 输出格式 Output Format 一个整数,奶牛们能获得的最大享受指数。 样例输入 Sample Input 5 2 4 -9 -4 -3 8 -6 样例输出 Sample Output 5 Hint 选择第3-4天,享受指数为-3+8=5。 时间限制 Time Limitation 1s 注释 Hint 50% 1≤N≤10000 100% 1≤N≤100000 1<=p<=q<=n
本题提供两种思路
1.线段树 复杂度(nlogn)
2.单调队列 复杂度(n)
具体实现
1.线段树:
首先预处理出来sum前缀和,
对于每一点i,我们只需要找到符合题意范围内最小的即可
并放入线段树中
对去查询每一个点,用线段树去查询i-q+1~i-p+1之间的最小值
然后去更新最大值
2.单调队列:
构造一个单调队列
当枚举到i的时候,用sum[i-p+1]去更新队列
具体实现看代码
1 #include <bits/stdc++.h> 2 #define ll long long 3 using namespace std; 4 inline ll read(){ 5 ll x=0;int f=1;char ch=getchar(); 6 while(!isdigit(ch)) {if(ch==‘-‘) f=-1;ch=getchar();} 7 while(isdigit(ch)) {x=x*10+ch-‘0‘;ch=getchar();} 8 return x*f; 9 } 10 const int MAXN=1e6+10; 11 namespace zhangenming{ 12 ll q[MAXN],head=1,tail=0,a[MAXN],maxn=-10000000000000,sum[MAXN]={},n,p,qq; 13 void init(){ 14 n=read();p=read();qq=read(); 15 for(int i=1;i<=n;i++){ 16 a[i]=read(); 17 sum[i]=sum[i-1]+a[i]; 18 //cout<<sum[i]<<‘ ‘; 19 } 20 //cout<<endl; 21 } 22 void solve(){ 23 q[++tail]=0; 24 for(int i=p;i<=n;i++){ 25 while(head<=tail&&i-q[head]>qq) head++; 26 //cout<<i<<‘ ‘<<q[head]<<‘ ‘; 27 ll tn=sum[i]-sum[q[head]]; 28 //cout<<tn<<endl; 29 maxn=max(maxn,tn); 30 //cout<<maxn<<endl; 31 tn=i-p+1; 32 while(sum[tn]<=sum[q[tail]]&&head<=tail) tail--; 33 q[++tail]=tn; 34 } 35 cout<<maxn<<endl; 36 } 37 } 38 int main(){ 39 //freopen("ab.in","r",stdin); 40 //freopen("ab.out","w",stdout); 41 using namespace zhangenming; 42 init(); 43 solve(); 44 return 0; 45 }
时间: 2024-10-18 11:49:19