链接:https://www.nowcoder.com/acm/contest/158/B
来源:牛客网
题目描述
给你一个长度为 n 的序列 a ,求最长的连续的严格上升区间的长度。
同时会进行 m 次修改,给定 x , y ,表示将 ax 修改为 y ,每次修改之后都要求输出答案。
输入描述:
第一行 2 个数 n,m,表示序列长度,修改次数; 接下来一行 n 个数表示 ; 接下来 m 行,每行 2 个数 x , y ,描述一次修改。
输出描述:
第一行 1 个数表示最初的答案; 接下来 m 行,第 i 行 1 个数表示第 i 次修改后的答案。
示例1
输入
4 3 1 2 3 4 3 1 2 5 3 7
输出
4 2 2 3
说明
序列变换如下: 1 2 3 4 1 2 1 4 1 5 1 4 1 5 7 4
备注:
n,m ≤ 100000,1 ≤ x ≤ n,1 ≤ ai,y ≤ 100
//最长区间
#include<iostream>
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<string>
#include<queue>
#include<map>
#include<stdlib.h>
using namespace std;
#define ll long long
#define rep(i,a,n) for (int i=a;i<n;i++)
#define LL ll
#define mem(arry,x) memset(arry,x,sizeof(arry))
#define L(x) x<<1
#define R(x) x<<1|1
#define in(a) scanf("%d",&a)
const int maxn=1e5+10;
const int maxm=1e5+100;
const double eps=1e-6;
const int INF=0x3f3f3f3f;
const ll MOD=1e9+7;
struct node
{
int rmax,lmax,l,r,smax;
}t[maxn*4];
int a[maxn];
void pushup(int c)
{
int lc=c<<1;
int rc=c<<1|1;
t[c].lmax=t[lc].lmax;
t[c].rmax=t[rc].rmax;
t[c].smax=max(t[lc].smax,t[rc].smax);
if(t[c].lmax==t[lc].r-t[lc].l+1&&a[t[rc].l]>a[t[lc].r]) t[c].lmax+=t[rc].lmax;
if(t[c].rmax==t[rc].r-t[rc].l+1&&a[t[rc].l]>a[t[lc].r]) t[c].rmax+=t[lc].rmax;
if(a[t[rc].l]>a[t[lc].r]) t[c].smax=max(t[c].smax,t[lc].rmax+t[rc].lmax);
t[c].smax=max(t[c].smax,max(t[c].lmax,t[c].rmax));
}
void build(int pos,int l,int r)
{
t[pos].rmax=t[pos].lmax=t[pos].smax=0;
t[pos].l=l;
t[pos].r=r;
if(l==r)
{
t[pos].rmax=t[pos].lmax=t[pos].smax=1;
return ;
}
int mid=(l+r)>>1;
build(pos<<1,l,mid);
build(pos<<1|1,mid+1,r);
pushup(pos);
}
void update(int pos,int id,int val)
{
if(t[pos].l==t[pos].r)
{
a[id]=val;
return ;
}
int mid=(t[pos].l+t[pos].r)>>1;
if(id<=mid) update(pos<<1,id,val);
else update (pos<<1|1,id,val);
pushup(pos);
}
int main()
{
int n,m;
while(~scanf("%d%d",&n,&m))
{
memset(a,0,sizeof(a));
rep(i,1,n+1) in(a[i]);
build(1,1,n);
printf("%d\n",t[1].smax);
rep(i,0,m)
{
int x,y;
in(x);in(y);
update(1,x,y);
printf("%d\n",t[1].smax);
}
}
}