题意:
Alyona造了n座塔。。。。现在要进行m此操作,每次是将[l,r]的塔的高度增加d,
询问每次操作后最长的山峰长度是多少。。
山峰定义为。。。[l,r]内的数,满足al < al+1 < al+2 < .. < amid > .. > ar-2 > ar-1 > ar
长度就是r - l + 1了
solution:
首先对原数列差分,ai = ai+1 - ai
这样山峰就是[l,r]内的数,前面的大于0,后面的小于0,然后长度再+1
这样修改不超过两个数
线段树维护前缀后缀。。。
定义L[o][0]:点o维护的区间内左起最长与左开头数字同号的长度
L[o][1]:点o维护的区间内左起最长与左开头数字先同号后异号的长度
转移写得有点长= =
#include<iostream>
#include<cstdio>
#include<algorithm>
#include<cmath>
#include<cstring>
#include<vector>
#include<queue>
#include<set>
#include<map>
#include<stack>
#include<bitset>
#include<ext/pb_ds/priority_queue.hpp>
using namespace std;
const int maxn = 3E5 + 30;
const int T = 4;
typedef long long LL;
int n,m,Max[maxn*T],L[maxn*T][2],R[maxn*T][2];
LL a[maxn],A[maxn],va[maxn*T][2];
int Judge(LL x)
{
return x > 0?1:x < 0?-1:0;
}
void maintain(int o,int l,int r)
{
int lc = (o<<1),rc = (o<<1|1),mid = (l + r) >> 1,tot = 0;
Max[o] = max(Max[lc],Max[rc]);
if (Judge(va[lc][1])*Judge(va[rc][0]) > 0)
{
if (va[lc][1] > 0) tot = R[lc][0] + L[rc][1];
else tot = R[lc][1] + L[rc][0];
Max[o] = max(Max[o],tot);
}
else if (va[lc][1] > 0 && va[rc][0] < 0)
{
tot = R[lc][0] + L[rc][0];
Max[o] = max(Max[o],tot);
}
if (L[lc][0] == mid - l + 1)
{
if (Judge(va[lc][1])*Judge(va[rc][0]) > 0)
{
L[o][0] = L[lc][0] + L[rc][0];
L[o][1] = L[lc][0] + L[rc][1];
}
else if (va[lc][1] != 0 && va[rc][0] != 0)
{
L[o][0] = L[lc][0];
L[o][1] = L[lc][0] + L[rc][0];
}
else L[o][0] = L[lc][0],L[o][1] = L[lc][1];
}
else if (L[lc][1] == mid - l + 1)
{
L[o][0] = L[lc][0];
if (Judge(va[lc][1])*Judge(va[rc][0]) > 0)
L[o][1] = L[lc][1] + L[rc][0];
else L[o][1] = L[lc][1];
}
else
{
L[o][0] = L[lc][0];
L[o][1] = L[lc][1];
}
if (R[rc][0] == r - mid)
{
if (Judge(va[lc][1])*Judge(va[rc][0]) > 0)
{
R[o][0] = R[rc][0] + R[lc][0];
R[o][1] = R[rc][0] + R[lc][1];
}
else if (va[lc][1] != 0 && va[rc][0] != 0)
{
R[o][0] = R[rc][0];
R[o][1] = R[rc][0] + R[lc][0];
}
else R[o][0] = R[rc][0],R[o][1] = R[rc][1];
}
else if (R[rc][1] == r - mid)
{
R[o][0] = R[rc][0];
if (Judge(va[lc][1])*Judge(va[rc][0]) > 0)
R[o][1] = R[rc][1] + R[lc][0];
else R[o][1] = R[rc][1];
}
else
{
R[o][0] = R[rc][0];
R[o][1] = R[rc][1];
}
va[o][0] = va[lc][0];
va[o][1] = va[rc][1];
}
void Modify(int o,int l,int r,int pos,LL x)
{
if (l == r)
{
A[l] += x; Max[o] = 1;
va[o][0] = va[o][1] = A[l];
L[o][0] = L[o][1] = 1;
R[o][0] = R[o][1] = 1;
return;
}
int mid = (l + r) >> 1;
if (pos <= mid) Modify(o<<1,l,mid,pos,x);
else Modify(o<<1|1,mid+1,r,pos,x);
maintain(o,l,r);
}
int main()
{
#ifdef DMC
freopen("DMC.txt","r",stdin);
#endif
cin >> n;
for (int i = 1; i <= n; i++) scanf("%I64d",&a[i]);
for (int i = 1; i < n; i++)
a[i] = a[i+1] - a[i],Modify(1,1,n-1,i,a[i]);
cin >> m;
while (m--)
{
int l,r,x;
scanf("%d%d%d",&l,&r,&x);
if (n == 1)
{
puts("1");
continue;
}
if (l > 1) Modify(1,1,n-1,l-1,x);
if (r < n) Modify(1,1,n-1,r,-x);
printf("%d\n",Max[1] + 1);
}
return 0;
}