HDU3308 LCIS

 

Time Limit: 2000MS   Memory Limit: 32768KB   64bit IO Format: %I64d & %I64u

Description

Given n integers. 
You have two operations: 
U A B: replace the Ath number by B. (index counting from 0) 
Q A B: output the length of the longest consecutive increasing subsequence (LCIS) in [a, b]. 

Input

T in the first line, indicating the case number. 
Each case starts with two integers n , m(0<n,m<=10 5). 
The next line has n integers(0<=val<=10 5). 
The next m lines each has an operation: 
U A B(0<=A,n , 0<=B=10 5
OR 
Q A B(0<=A<=B< n). 

Output

For each Q, output the answer.

Sample Input

1
10 10
7 7 3 3 5 9 9 8 1 8 
Q 6 6
U 3 4
Q 0 1
Q 0 5
Q 4 7
Q 3 5
Q 0 2
Q 4 6
U 6 10
Q 0 9

Sample Output

1
1
4
2
3
1
2
5

Source

 
 
线段树维护每个区间的三个值:从左开始数的最长单调上升序列,本区间内最长答案,以最右为结尾的最长单调上升序列。
每次合并的时候,如果左子树的右端点的值小于右子树的左端点的值,那么两段序列可以接起来……
 1 #include<iostream>
 2 #include<cstdio>
 3 #include<cstring>
 4 #include<algorithm>
 5 #include<cmath>
 6 #define ls l,mid,rt<<1
 7 #define rs mid+1,r,rt<<1|1
 8 using namespace std;
 9 const int mxn=100010;
10 int n,m;
11 int d[mxn];
12 struct node{
13     int cnt;int lans,rans;
14 }t[mxn<<2];
15 void update(int p,int l,int r,int rt){
16     if(l==r)return;
17     int mid=(l+r)>>1;
18     if(p<=mid)update(p,ls);
19     else update(p,rs);
20     t[rt].cnt=max(t[rt<<1].cnt,t[rt<<1|1].cnt);
21     t[rt].lans=t[rt<<1].lans;t[rt].rans=t[rt<<1|1].rans;
22     if(d[mid]<d[mid+1]){
23         t[rt].cnt=max(t[rt].cnt,t[rt<<1].rans+t[rt<<1|1].lans);
24         if(t[rt<<1].lans==mid-l+1)
25             t[rt].lans=t[rt<<1].lans+t[rt<<1|1].lans;
26         if(t[rt<<1|1].rans==r-mid)
27             t[rt].rans=t[rt<<1|1].rans+t[rt<<1].rans;
28     }
29     return;
30 }
31 void Build(int l,int r,int rt){
32     if(l==r){
33         t[rt].cnt=t[rt].lans=t[rt].rans=1;
34         return;
35     }
36     int mid=(l+r)>>1;
37     Build(ls);
38     Build(rs);
39     t[rt].cnt=max(t[rt<<1].cnt,t[rt<<1|1].cnt);
40     t[rt].lans=t[rt<<1].lans;
41     t[rt].rans=t[rt<<1|1].rans;
42     if(d[mid]<d[mid+1]){
43         t[rt].cnt=max(t[rt].cnt,t[rt<<1].rans+t[rt<<1|1].lans);
44         if(t[rt<<1].lans==mid-l+1)
45             t[rt].lans=t[rt<<1].lans+t[rt<<1|1].lans;
46         if(t[rt<<1|1].rans==r-mid)
47             t[rt].rans=t[rt<<1|1].rans+t[rt<<1].rans;
48     }
49     return;
50 }
51 int query(int L,int R,int l,int r,int rt){
52     if(L<=l && r<=R) return t[rt].cnt;
53     int mid=(l+r)>>1;
54     if(R<=mid)return query(L,R,ls);
55     if(mid<L)return query(L,R,rs);
56     else{
57         int res=max(query(L,R,ls),query(L,R,rs));
58         if(d[mid]<d[mid+1]){//如果结点所存答案长于区间长度,实际答案等于区间长度,用min维护
59             res=max(res,(min(t[rt<<1].rans,mid-L+1)+min(t[rt<<1|1].lans,R-mid)));
60         }
61         return res;
62     }
63 }
64 int main(){
65     int T;
66     scanf("%d",&T);
67     while(T--){
68         memset(t,0,sizeof 0);
69         int i,j;
70         scanf("%d%d",&n,&m);
71         for(i=1;i<=n;i++)scanf("%d",&d[i]);
72         Build(1,n,1);
73         char op[2];int a,b;
74         for(i=1;i<=m;i++){
75             scanf("%s%d%d",op,&a,&b);
76             if(op[0]=='U'){
77                 d[++a]=b;
78                 update(a,1,n,1);
79             }
80             if(op[0]=='Q'){
81                 
82                 printf("%d\n",query(a+1,b+1,1,n,1));
83             }
84         }    
85     }
86     return 0;
87 }

 

 
posted @ 2016-08-19 22:12  SilverNebula  阅读(199)  评论(0编辑  收藏  举报
AmazingCounters.com