线段树的点更新+求区间的最大两个数之和

11 篇文章 0 订阅
8 篇文章 0 订阅

KGSS - Maximum Sum


You are given a sequence A[1], A[2], ..., A[N] ( 0 ≤ A[i] ≤ 10^8 , 2 ≤ N ≤ 10^5 ). There are two types of operations and they are defined as follows:

Update:

This will be indicated in the input by a 'U' followed by space and then two integers i and x.

U i x, 1 ≤ i ≤ N, and x, 0 ≤ x ≤ 10^8.

This operation sets the value of A[i] to x.

Query:

This will be indicated in the input by a 'Q' followed by a single space and then two integers i and j.

Q x y, 1 ≤ x < y ≤ N.

You must find i and j such that x ≤ i, j ≤ y and i != j, such that the sum A[i]+A[j] is maximized. Print the sum A[i]+A[j].

Input

The first line of input consists of an integer N representing the length of the sequence. Next line consists of N space separated integers A[i]. Next line contains an integer Q, Q ≤ 10^5, representing the number of operations. Next Q lines contain the operations.

Output

Output the maximum sum mentioned above, in a separate line, for each Query.

Example

Input:
5
1 2 3 4 5
6
Q 2 4
Q 2 5


U 1 6
Q 1 5
U 1 7
Q 1 5

Output:
7
9
11
12
 
  
 
  
#include <bits/stdc++.h>
#include<limits.h>
using namespace std;
struct Node
{
   int first;
   int second;
};
Node tree[300015];
int a[100005];
void build(int node, int start, int end, Node tree[], int a[])
{
	if (start == end)
		{
		    tree[node].first=a[start];
		    tree[node].second=INT_MIN;
		}
	else
	{
		int mid = (start + end) / 2;
		build(2 * node, start, mid, tree, a);
		build(2 * node + 1, mid + 1, end, tree, a);
		 tree[node].first=
		 max(tree[2*node].first,tree[2*node+1].first);
		 tree[node].second=
		 min(max(tree[2*node].first,tree[2*node+1].second),
             max(tree[2*node].second,tree[2*node+1].first)
             );
	}
}

Node query(int node,int start,int end,int l,int r,Node tree[])
{
    Node result;
    result.first=result.second=0;
    if(start>r||end<l)
        return result;
        //return result;//
    if(start>=l&&end<=r)
        return tree[node];
    int mid=(start+end)/2;
    if(l>mid)
        return query(2*node+1,mid+1,end,l,r,tree);
    if(r<=mid)
        return query(2*node,start,mid,l,r,tree);
    Node left=query(2*node,start,mid,l,r,tree);
    Node right=query(2*node+1,mid+1,end,l,r,tree);
    result.first=
          max(left.first,right.first);
    result.second=
    min(max(left.first,right.second),
        max(left.second,right.first)
        );
        return result ;

}
void update(int node,int start,int end,int idx,int val,Node tree[],int a[])
{
    if(start==end)
    {
        a[idx]=val;
        tree[node].first=val;
        tree[node].second=INT_MIN;
    }
    else{
        int mid=(start+end)/2;
        if(idx<=mid)
            update(2*node,start,mid,idx,val,tree,a);
        else
            update(2*node+1,mid+1,end,idx,val,tree,a);
        tree[node].first=
		 max(tree[2*node].first,tree[2*node+1].first);
		 tree[node].second=
		 min(max(tree[2*node].first,tree[2*node+1].second),
             max(tree[2*node].second,tree[2*node+1].first)
             );
	}

}
int main()
{
    ios::sync_with_stdio(false);
    int n,q;
    cin>>n;
    for(int i=1;i<=n;i++)
        cin>>a[i];
    build(1,1,n,tree,a);
    cin>>q;
    while(q--)
    {
        char b;
        int x,y;
        cin>>b>>x>>y;
        if(b=='Q')
        {
          Node result=query(1,1,n,x,y,tree);
           cout<<result.first+result.second<<endl;
        }
            else if(b=='U')
            {
                update(1,1,n,x,y,tree,a);
            }
    }
    return 0;
}


  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值