1. 程式人生 > >【JZOJ A組】逛公園

【JZOJ A組】逛公園

Description

策策由於在noip2017考試當天去逛公園了,沒能出現在考場上,轉眼到了noip2018,策策的公園也悄然轉變,策策能否克服誘惑,成功坐在考場上呢?
問題描述
策策同學特別喜歡逛公園,公園可以看做有n個景點的序列,每個景點會給策策帶來di 的愉悅度,策策初始有x0 的愉悅度,然而愉悅度也是有上限的,他在每個景點的愉悅度上限為li ,策策想要從 l 到 r這一段景點中選擇一段景點參觀(從這一段的左端點逛到這一段的右端點),策策想知道他最終的愉悅度的最大值是多少,你能幫幫他嗎?(區間可以為空,也就是說答案最小為x0 )

Input

第一行兩個數n,q 表示景點序列長度 和 詢問個數
第二行n個數 表示di
第三行n個數 表示li
接下來q行,每行3個數:
表示 l ,r ,x0
下標均從1開始

Output

共q行,每行1個數表示愉悅度的最大值

Sample Input

6 3
0 5 3 2 0 4
8 10 8 1 9 9
1 3 9
2 6 3
3 4 0

Sample Output

10
8
3

樣例說明
詢問1 初始愉悅度9 只逛第2個公園 9+5=14 大於l2 ans=10
詢問2 初始愉悅度3 從2逛到3 3+5+3=11 大於l3 ans=8
詢問3 初始愉悅度0 只逛第3個公園 ans=3

Data Constraint

在這裡插入圖片描述

思路

這題滿分有點難,我選擇85暴力

這東西很像子段最大和,加一個優化就可以拿到85的好成績

程式碼

#pragma GCC optimize(3)
#include<iostream>
#include<cstdio>
#include<cstring>
using namespace std;
int n,q;
struct A
{
	int x,y;
}a[40077];
int main()
{
	freopen("park.in","r",stdin); freopen("park.out","w",stdout);
	scanf("%d%d",&n,&q);
	for(int i=1; i<=n; i++) scanf("%d",&a[i].x);
	for(int i=1; i<=n; i++) scanf("%d",&a[i].y);
	while(q--)
	{
		int l,r;
		long long s=0,ans=0,x;
		scanf("%d%d%lld",&l,&r,&x); ans=s=x;
		for(int i=l; i<=r; i++)
		{
			s=max(x,min(s+1ll*a[i].x,1ll*a[i].y)); ans=max(ans,s);
		}
		printf("%lld\n",ans);
	}
}