[2020 Niuke Algorithm Competition introductory class ninth exercise] Find the maximum value greedy + line segment tree

Topic link: Find the maximum value

Title

Given a sequence of length n, let you find the maximum value of (a[j]-a[i]) / (ji) [1<=i<j<=n] in the entire sequence. There will be q operations, and each operation will select a number in a position and change it to y. The maximum value is output after each operation.

answer

It is not difficult to see that we construct a Cartesian product <i,a[i]>, then (a[j]-a[i]) / (ji) is to find the maximum slope between two points in a two-dimensional coordinate system In fact, it is easy to figure out that the two points of the maximum slope must be continuous. Since the x coordinates of these points will not be the same, the maximum value of (a[j]-a[i]) / (ji) is the maximum value of the difference between adjacent n sequences.

We can construct a difference sequence: a 2 − a 1, a 3 − a 2,...., An − an − 1 {a_2-a_1,a_3-a_2,....,a_n-a_{n-1 }}a2a1,a3a2,....,anan1= b 1 , b 2 , . . . . . , b n − 1 {b_1,b_2,.....,b_{n-1}} b1,b2,.....,bn1
We only need to maintain the maximum value of this difference sequence.

Pay attention to modify ai {a_i}aiTime will affect the two differential values.
If we modify ai to v {a_i to v}aiv时, d i = a i + 1 − a i , d i − 1 = a i − a i − 1 {d_i=a_{i+1}-a_i,d_{i-1}=a_i-a_{i-1}} di=ai+1ai,di1=aiai1,那么 d i + = a i − v , d i − 1 + = v − a i {d_i+=a_i-v,d_{i-1}+=v-a_i} di+=aivdi1+=vai

Note that the numbers on both sides have only one effect on the value of the differential sequence, such as modifying an {a_n}an, Only for dn − 1 {d_{n-1}}dn1Has an impact, so there is no need to deal with non-existent dn {d_n}dnto modify.

Code

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<bitset>
#include<cassert>
#include<cctype>
#include<cmath>
#include<cstdlib>
#include<ctime>
#include<deque>
#include<iomanip>
#include<list>
#include<map>
#include<queue>
#include<set>
#include<stack>
#include<vector>
using namespace std;
//extern "C"{void *__dso_handle=0;}
typedef long long ll;
typedef long double ld;
#define fi first
#define se second
#define pb push_back
#define mp make_pair
#define pii pair<int,int>
#define lowbit(x) x&-x

const double PI=acos(-1.0);
const double eps=1e-6;
const ll mod=1e9+7;
const ll inf=3e9;
const int maxn=2e5+10;
const int maxm=100+10;
#define ios ios::sync_with_stdio(false);cin.tie(0);cout.tie(0);

int gcd(int a,int b) {
    
     return b==0 ?a:gcd(b,a%b); }

ll d[maxn],a[maxn];
ll tree[maxn<<2];

void build(int p,int l,int r)
{
    
    
	if(l==r) {
    
     tree[p]=d[l]; return;}
	int mid=l+(r-l)/2;
	build(p*2,l,mid);
	build(p*2+1,mid+1,r);
	tree[p]=max(tree[p*2],tree[p*2+1]);
}
void add(int p,int l,int r,int pos,int v)
{
    
    
	if(l==r) {
    
     tree[p]+=v; return ; }
	int mid=l+(r-l)/2;
	if(pos<=mid) add(p*2,l,mid,pos,v);
	if(pos>mid) add(p*2+1, mid+1, r, pos, v);
	tree[p]=max(tree[p*2],tree[p*2+1]);
}

ll query_max(int p,int l,int r,int ql,int qr)
{
    
    
	if(ql<=l && qr>=r) return tree[p];
	int mid=l+(r-l)/2;
	ll ans=-inf;
	if(ql<=mid) ans=max(ans,query_max(p*2, l, mid, ql, qr));
	if(qr>mid) ans=max(ans,query_max(p*2+1, mid+1, r, ql, qr));
	return ans;
}

int main()
{
    
    
	int n;
	while(scanf("%d",&n)==1)
	{
    
    
		for(int i=1;i<=n;i++) scanf("%lld",&a[i]);
		for(int i=2;i<=n;i++) d[i-1]=a[i]-a[i-1];
		build(1,1,n-1);
		int m; scanf("%d",&m);
		while(m--)
		{
    
    
			ll pos,v; scanf("%lld%lld",&pos,&v);
			if(pos<n) add(1, 1, n-1, pos, a[pos]-v);
			if(pos>1) add(1, 1, n-1, pos-1, v-a[pos]);
			a[pos]=v;
			printf("%lld.00\n",query_max(1, 1, n-1, 1, n-1));
		}
	}
}

Guess you like

Origin blog.csdn.net/weixin_44235989/article/details/108099512
Recommended