瑶瑶想要玩滑梯
Time Limit: 2000/1000MS (Java/Others)
Memory Limit: 512000/256000KB (Java/Others)
Problem Description
众所周知,瑶瑶(tsyao)是个贪玩的萌妹子,特别喜欢闹腾,恰好今天是一个风和日丽的日子,瑶瑶嚷着让姐姐带她去去公园玩滑梯,可是公园的滑梯比较独特,由单位积木搭成,积木是排成一排搭好,每列有xi个积木,共n列。小明能够对积木进行m次操作:
1.U L R yi : 将[L,R]列的积木高度全都改为yi
2.Q L R : 查询[L,R]列最长连续上升的列长度(LCIS)
知道[L,R]列最长连续上升的列长度过后,瑶瑶就可以开开心心地玩滑梯啦!
Ps:连续上升的列长度指对于一段合法区间,都有 。
话说积木是平的,瑶瑶是怎么从高处滑到低处的呢??作为姐姐也不知道,很想知道吧?你去问她吧。。
Input
第一行 两个整数n,m;
第二行 n个整数,分别为[1,n]区间每列积木个数;
接下来m行为m个操作
Output
输出x行,每行为每次操作2的查询结果。
Sample Input
5 4 2 1 2 3 1 Q 1 4 Q 2 5 U 2 4 3 Q 1 5
Sample Output
3 3 2
Hint
对于 100%的数据,有1 ≤ n ≤ 10^5 , 1 ≤ m ≤ 10^5 , 1 ≤ xi ≤ 10^8。
单组输入,共10组数据。
Source
tsyao
Manager
线段树区间更新,区间合并,维护每个区间的两个端点。
#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;
#include <iostream>
#include <cmath>
#include <queue>
#include <vector>
#include <set>
#include <cstdlib>
#include <time.h>
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
const int Maxn=1e5+5;
const int N=Maxn*7+5;
int maxn[N],maxl[N],maxr[N];
int numl[N],numr[N],vis[N];
int a[Maxn];
void PushUp(int l,int r,int rt)
{
int m=(l+r)>>1;
maxn[rt]=max(maxn[rt<<1],maxn[rt<<1|1]);
maxl[rt]=maxl[rt<<1];
maxr[rt]=maxr[rt<<1|1];
numl[rt]=numl[rt<<1];
numr[rt]=numr[rt<<1|1];
if(numr[rt<<1]<numl[rt<<1|1])
{
maxn[rt]=max(maxn[rt],maxr[rt<<1]+maxl[rt<<1|1]);
if(maxl[rt]==m-l+1)
maxl[rt]+=maxl[rt<<1|1];
if(maxr[rt]==r-m)
maxr[rt]+=maxr[rt<<1];
}
}
void Pushdown(int rt)
{
if(vis[rt])
{
vis[rt<<1]=vis[rt<<1|1]=vis[rt];
numl[rt<<1]=numr[rt<<1]=vis[rt<<1];
maxl[rt<<1]=maxr[rt<<1]=maxn[rt<<1]=1;
numl[rt<<1|1]=numr[rt<<1|1]=vis[rt<<1|1];
maxl[rt<<1|1]=maxr[rt<<1|1]=maxn[rt<<1|1]=1;
vis[rt]=0;
}
}
void build(int l,int r,int rt)
{
vis[rt]=0;
if(l==r)
{
maxn[rt]=maxl[rt]=maxr[rt]=1;
numl[rt]=numr[rt]=a[l];
}
else
{
int m=(l+r)/2;
build(lson);
build(rson);
PushUp(l,r,rt);
}
}
void update(int L,int R,int c,int l,int r,int rt)
{
if(L<=l &&r<=R)
{
maxn[rt]=maxl[rt]=maxr[rt]=1;
numl[rt]=numr[rt]=vis[rt]=c;
return;
}
Pushdown(rt);
int m=(l+r)>>1;
if(L<=m)update(L,R,c,lson);
if(m<R)update(L,R,c,rson);
PushUp(l,r,rt);
}
int query(int L,int R,int l,int r,int rt)
{
if(L<=l &&r<=R)
return maxn[rt];
Pushdown(rt);
int tmp1,tmp2,tmp3;
tmp1=tmp2=tmp3=0;
int m=(l+r)>>1;
if(L<=m)tmp1=query(L,R,lson);
if(m<R)tmp2=query(L,R,rson);
if(L<=m &&m<R)
{
if(numr[rt<<1]<numl[rt<<1|1])
tmp3=min(maxr[rt<<1],m-L+1)+min(maxl[rt<<1|1],R-m);
}
return max(tmp1,max(tmp2,tmp3));
}
int main()
{
int n,m;
char pp[2];
while(scanf("%d%d",&n,&m)!=EOF)
{
for(int i=1; i<=n; i++)
scanf("%d",&a[i]);
build(1,n,1);
int x,y,z;
for(int i=1; i<=m; i++)
{
scanf("%s",pp);
if(pp[0]=='Q')
{
scanf("%d%d",&x,&y);
printf("%d\n",query(x,y,1,n,1));
}
else
{
scanf("%d%d%d",&x,&y,&z);
update(x,y,z,1,n,1);
}
}
}
return 0;
}