首页 > 代码库 > hdu--3308 LCIS(线段树+区间合并)

hdu--3308 LCIS(线段树+区间合并)

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
题意:给出一列n个数,进行m次操作,把第a的值变为b,查询[a,b]之间的最长连续上升子序列的长度,对于每个查询输出结果
思路:用线段树进行存当前节点的最大长度以及左边开始的长度和右边结束的长度,然后向上更新。查询时和线段树的查询一样,就是在查询时要注意对左右边界的更新。
AC代码:
技术分享
  1 #include<iostream>  
  2 #include<fstream>  
  3 #include<iomanip>  
  4 #include<cstdio>  
  5 #include<cstring>  
  6 #include<algorithm>  
  7 #include<cstdlib>  
  8 #include<cmath>  
  9 #include<set>  
 10 #include<map>  
 11 #include<queue>  
 12 #include<stack>  
 13 #include<string>  
 14 #include<vector>  
 15 #include<ctime>  
 16 #include<sstream>  
 17 #include<cassert> 
 18 using namespace std;
 19 const int maxn=100005;
 20 struct note
 21 {
 22     int l,r,lm,rm,m;
 23 } a[maxn<<2];
 24 int p[maxn];
 25 int build(int l,int r,int k)
 26 {
 27     a[k].l=l;
 28     a[k].r=r;
 29     a[k].lm=a[k].rm=a[k].m=0;
 30     if(l==r)
 31     {
 32         return 0;
 33     }
 34     int mid=(l+r)/2;
 35     build(l,mid,k*2);
 36     build(mid+1,r,k*2+1);
 37     return 0;
 38 }
 39 int pushup(int k)
 40 {
 41     if(p[a[k*2].r]>=p[a[k*2+1].l])
 42     {
 43         a[k].m=max(a[k*2].m,a[k*2+1].m);
 44         a[k].lm=a[k*2].lm;
 45         a[k].rm=a[k*2+1].rm;
 46     }
 47     else
 48     {
 49         a[k].m=max(max(a[k*2].rm+a[k*2+1].lm,a[k*2].m),a[k*2+1].m);
 50         if(a[k*2].lm==(a[k*2].r-a[k*2].l+1))
 51             a[k].lm=a[k*2].lm+a[k*2+1].lm;
 52         else
 53             a[k].lm=a[k*2].lm;
 54         if(a[k*2+1].rm==(a[k*2+1].r-a[k*2+1].l+1))
 55             a[k].rm=a[k*2].rm+a[k*2+1].rm;
 56         else
 57             a[k].rm=a[k*2+1].rm;
 58     }
 59     return 0;
 60 }
 61 int ins(int n,int d,int k)
 62 {
 63     if(a[k].l==a[k].r&&a[k].l==d)
 64     {
 65         a[k].rm=a[k].lm=a[k].m=1;
 66         return 0;
 67     }
 68     if(a[k*2].r>=d) ins(n,d,k*2);
 69     else if(a[k*2+1].l<=d) ins(n,d,k*2+1);
 70     pushup(k);
 71     return 0;
 72 }
 73 int sea(int l,int r,int k)
 74 {
 75     if(l==a[k].l&&a[k].r==r)
 76     {
 77         return a[k].m;
 78     }
 79     if(a[k*2].r>=r) return sea(l,r,k*2);
 80     else if(a[k*2+1].l<=l) return sea(l,r,k*2+1);
 81     else
 82     {
 83         int t1=sea(l,a[k*2].r,k*2);
 84         int t2=sea(a[k*2+1].l,r,k*2+1);
 85         int ans=max(t1,t2);
 86         int sum=0;
 87         if(p[a[k*2].r]<p[a[k*2+1].l])
 88         sum=min(a[k*2].r-l+1,a[k*2].rm)+min(r-a[k*2].r,a[k*2+1].lm);
 89         return max(ans,sum);
 90     }
 91 }
 92 int main()
 93 {
 94     int n,m,t,c,b;
 95     scanf("%d",&t);
 96     {
 97         for(int kk=1; kk<=t; kk++)
 98         {
 99             scanf("%d%d",&n,&m);
100             build(1,n,1);
101             for(int i=1; i<=n; i++)
102             {
103                 scanf("%d",&c);
104                 p[i]=c;
105                 ins(c,i,1);
106             }
107             char s[10];
108             for(int i=0; i<m; i++)
109             {
110                 scanf("%s",s);
111                 if(s[0]==U)
112                 {
113                     scanf("%d%d",&c,&b);
114                     p[c+1]=b;
115                     ins(b,c+1,1);
116                 }
117                 else
118                 {
119                     scanf("%d%d",&c,&b);
120                     printf("%d\n",sea(c+1,b+1,1));
121                 }
122             }
123         }
124     }
125     return 0;
126 }
View Code

 

hdu--3308 LCIS(线段树+区间合并)