GSS 시리즈 1 - 8
Descripition
You are given a sequence A[1], A[2], …, A[N] . ( |A[i]| ≤ 15007 , 1 ≤ N ≤ 50000 ). A query is defined as follows: Query(x,y) = Max { a[i]+a[i+1]+…+a[j] ; x ≤ i ≤ j ≤ y }. Given M queries, your program must output the results of these queries.
Input The first line of the input file contains the integer N. In the second line, N numbers follow. The third line contains the integer M. M lines follow, where line i contains 2 numbers xi and yi. Output Your program should output the results of the M queries, one query per line.
Example Input: 3 -1 2 3 1 1 2 Output: 2
Solution
이 문 제 는 주어진 구간 의 최대 부분 과 선분 트 리 로 만 들 면 된다 는 것 이다.그러나 잘 처리 해 야 할 점 은 이 단락 의 최대 부분 과 두 개의 구간 을 뛰 어 넘 을 수 있 기 때문에 우 리 는 왼쪽 에서 최대 치, 오른쪽 에서 최대 치 를 기록 해 야 한다.그리고 pushup 에서 매번 업데이트 해 주세요.코드 를 보 세 요.https://www.cnblogs.com/ztz11/p/9343366.html 우리 가 이 문 제 를 푸 는 데 있어 서 먼저 생각해 야 할 것 은 두 구간 이 어떻게 합병 되 는 지 하 는 것 이다.
합병 후 가장 큰 부분 과 원래 왼쪽 아들 의 것 이 었 거나 원래 오른쪽 아들 의 것 이 었 음 이 분명 하 다.
또 하 나 는 두 아들 을 합병 한 후에 중간 에 새로 생 성 된 것 일 수도 있다.
그래서 각 노드 마다 네 개의 요 소 를 유지 합 니 다.
각각 그 가 관할 하 는 구간 과 그 가 관할 하 는 구간 중 최대 연속 부분 과
왼쪽부터 최대 연속 자 단 과
오른쪽 부터 최대 연속 부분 과
이때 우 리 는 이렇게 이동 할 수 있다.
sum (화) 는 말 할 필요 가 없습니다.
이 층 의 왼쪽 부터 최대 연속 부분 과 = max (왼쪽 아들 의 왼쪽 부터 최대 연속 부분 과 왼쪽 아들 의 합 + 오른쪽 아들 의 왼쪽 부터 최대 연속 부분 과)
이 층 의 왼쪽 부터 최대 연속 부분 과 방법 이 같 습 니 다.
이 층 의 최대 연속 자 단 과 = max (왼쪽 아들 의 최대 연속 자 단 과 오른쪽 아들 의 최대 연속 자 단 과, (왼쪽 아들 이 오른쪽 에서 시작 하 는 최대 연속 필드 와 + 오른쪽 아들 이 왼쪽 에서 시작 하 는 최대 연속 자 단 과 (즉 합병 후 생 성 되 는 중간 최대 자 단))
OK, 퀘 스 트 완성
조회
Code
#include
#include
#include
#include
#include
#define ls (rt<<1)
#define rs (rt<<1|1)
#define INF 0x3f3f3f3f
using namespace std;
struct node{
int lmax,rmax,max,sum;
// , ( )
//
node(int x=0) {
sum=max=lmax=rmax=x;
}
}tree[1000001];
int ql,qr,n,m;
inline int read(){
int x=0,w=1;char ch;
while(ch!='-'&&(ch<'0'||ch>'9')) ch=getchar();
if(ch=='-') w=-1,ch=getchar();
while(ch>='0'&&ch<='9') x=(x<<3)+(x<<1)+(ch-48),ch=getchar();
return x*w;
}
node pushup(node x,node y) {
node ans;
ans.sum=x.sum+y.sum;//
ans.max=max(x.rmax+y.lmax,max(x.max,y.max));// + ,
ans.lmax=max(x.lmax,x.sum+y.lmax);
ans.rmax=max(y.rmax,y.sum+x.rmax);//
return ans;
}
void build(int rt,int l,int r) {
if(l==r) {
int x;
x=read();
tree[rt]=node(x);
return ;
}
int mid=(l+r)>>1;
build(ls,l,mid);
build(rs,mid+1,r);
tree[rt]=pushup(tree[ls],tree[rs]);
}
node query(int rt,int l,int r) {
if(ql<=l&&r<=qr) return tree[rt];
// , ,
node x(-INF),y(-INF);
x.sum=y.sum=0;
int mid=(l+r)>>1;
if(ql<=mid) x=query(ls,l,mid);
if(qr>mid) y=query(rs,mid+1,r);
return pushup(x,y);
}
int main(){
freopen("gss1.in","r",stdin);
freopen("gss1.out","w",stdout);
while(~scanf("%d",&n)) {
build(1,1,n);
m=read();
while(m--) {
ql=read();qr=read();
printf("%d
",query(1,1,n).max);
}
}
return 0;
}
이 내용에 흥미가 있습니까?
현재 기사가 여러분의 문제를 해결하지 못하는 경우 AI 엔진은 머신러닝 분석(스마트 모델이 방금 만들어져 부정확한 경우가 있을 수 있음)을 통해 가장 유사한 기사를 추천합니다:
정수 반전Udemy 에서 공부 한 것을 중얼거린다 Chapter3【Integer Reversal】 (예) 문자열로 숫자를 반전 (toString, split, reverse, join) 인수의 수치 (n)가 0보다 위 또는 ...
텍스트를 자유롭게 공유하거나 복사할 수 있습니다.하지만 이 문서의 URL은 참조 URL로 남겨 두십시오.
CC BY-SA 2.5, CC BY-SA 3.0 및 CC BY-SA 4.0에 따라 라이센스가 부여됩니다.