UESTC360 Another LCIS:http://acm.uestc.edu.cn/#/problem/show/360
Time Limit: 1000MS | Memory Limit: 65535KB | 64bit IO Format: %lld & %llu |
Description
For a sequence
is a CIS
(Continuous Increasing Subsequence). The longest CIS
of a sequence is called the LCIS
(Longest Continuous Increasing Subsequence).
In this problem, we will give you a sequence first, and then some add
operations and some query
operations. An add operation adds a value to each member in a specified interval. For a query operation, you should output the length of the LCIS of a specified interval.
Input
The first line of the input is an integer
, which stands for the number of test cases you need to solve.
Every test case begins with two integers
, , where is the size of the sequence, and is the number of queries. are specified on the next line, and then queries follow. Every query begins with a charactera
or
q
.
a
is followed by three integers
,
,
, meaning that add
to members in the interval
(including
,
), and
q
is followed by two integers
,
, meaning that you should output the length of the
LCIS
of interval
.
;
;
;
.
Output
For every test case, you should output Case #k:
on a single line first, where
. Then for every q
query, output the answer on a single line. See sample for more details.
Sample Input
1
5 6
0 1 2 3 4
q 1 4
a 1 2 -10
a 1 1 -6
a 5 5 -4
q 2 3
q 4 4
Sample Output
Case #1:
4
2
1
Hint
Source
显然需要用到lazy标记……但怎么更新呢?当一个区间内的值同时变化时,该区间内的LCIS是不变的,因此这里新开了两个数组lvalue和rvalue,
分别记录区间最左边的值和最右边的值,这样在更新时只需更新这两个值,便可达到相同的效果。其他的跟上一篇的做法大致一样
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <iostream>
#include <map>
#include <cmath>
#include <vector>
using namespace std;
#define lson l,mid,rt<<1
#define rson mid+1,r,rt<<1|1
#define inf 0x3f3f3f3f
const int maxn= 100000+7;
typedef long long ll;
int lx[maxn<<2],mx[maxn<<2],rx[maxn<<2],color[maxn<<2];
int lvau[maxn<<2],rvau[maxn<<2];
int a[maxn];
void pushup(int rt,int len) {
lvau[rt] = lvau[rt<<1];
rvau[rt] = rvau[rt<<1|1];
lx[rt] = lx[rt<<1];
rx[rt] = rx[rt<<1|1];
if((lx[rt] == (len-(len>>1))) && (rvau[rt<<1] < lvau[rt<<1|1]))lx[rt] += lx[rt<<1|1];
if((rx[rt] == (len>>1)) && (rvau[rt<<1] < lvau[rt<<1|1]))rx[rt] += rx[rt<<1];
mx[rt] = max(max(mx[rt<<1],mx[rt<<1|1]),(rvau[rt<<1] < lvau[rt<<1|1])?rx[rt<<1]+lx[rt<<1|1]:0);
}
void build(int l,int r,int rt) {
color[rt] = 0;
lx[rt] = rx[rt] = mx[rt] = 0;
if(l > r)return;
if(l == r) {
scanf("%d",&a[l]);
lvau[rt] = rvau[rt] = a[l];
lx[rt] = mx[rt] = rx[rt] = 1;
return;
}
int mid = l+r>>1;
build(lson);
build(rson);
pushup(rt,r-l+1);
}
void pushdown(int rt) {
if(color[rt]) {
lvau[rt<<1] += color[rt];
rvau[rt<<1] += color[rt];
lvau[rt<<1|1] += color[rt];
rvau[rt<<1|1] += color[rt];
color[rt<<1] += color[rt];
color[rt<<1|1] += color[rt];
color[rt] = 0;
}
}
void update(int L,int R,int w,int l,int r,int rt) {
if(L <= l && r <= R) {
color[rt] += w;
lvau[rt] += w;
rvau[rt] += w;
return;
}
if(l > r)return;
pushdown(rt);
int mid = l+r>>1;
if(L <= mid)update(L,R,w,lson);
if(R > mid) update(L,R,w,rson);
pushup(rt,r-l+1);
}
int query(int L,int R,int l,int r,int rt) {
if(L <= l && r <= R) {
return mx[rt];
}
int mid = l+r>>1;
pushdown(rt);
if(R <= mid)return query(L,R,lson);
else if(L > mid)return query(L,R,rson);
else {
int ltmp = query(L,mid,lson);
int rtmp = query(mid+1,R,rson);
int sum = 0;
if(lvau[rt<<1|1] > rvau[rt<<1]) {
sum = min(mid-L+1,rx[rt<<1])+min(R-mid,lx[rt<<1|1]);
}
return max(sum,max(ltmp,rtmp));
}
}
int main() {
// freopen("in.txt","r",stdin);
// freopen("out.txt","w",stdout);
int n,m,b,c,t,w,ca = 1;
char ss[10];
scanf("%d",&t);
while(t--) {
scanf("%d%d",&n,&m);
build(1,n,1);
printf("Case #%d:\n",ca++);
for(int i = 1; i <= m; i++) {
scanf("%s",ss);
if(ss[0] == 'a') {
scanf("%d%d%d",&b,&c,&w);
update(b,c,w,1,n,1);
} else {
scanf("%d%d",&b,&c);
printf("%d\n",query(b,c,1,n,1));
}
}
}
return 0;
}