HDU 3308 线段树区间合并

LCIS

Time Limit: 6000/2000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others)
Total Submission(s): 3151    Accepted Submission(s): 1389


Problem 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<=105).
The next line has n integers(0<=val<=105).
The next m lines each has an operation:
U A B(0<=A,n , 0<=B=105)
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
典型线段树区间合并。
代码:
#include<iostream>
#include<stdio.h>
#include<algorithm>
#include<map>
#include<set>
#include<stack>
#include<string.h>
#include<string>
#include<queue>
#include<vector>
using namespace std;
const int maxn=111111;
#define L(x) 2*x
#define R(x) 2*x+1
struct node
{
       int l,r,lsum,rsum,vsum;
       int mid(){return (l+r)>>1;}
       int len(){return r-l+1;}
}tree[5*maxn];
int a[maxn];
void pushup(int p)
{
       tree[p].lsum=tree[L(p)].lsum;
       tree[p].rsum=tree[R(p)].rsum;
       if(tree[L(p)].lsum==tree[L(p)].len()&&a[tree[L(p)].r]<a[tree[R(p)].l])tree[p].lsum+=tree[R(p)].lsum;
       if(tree[R(p)].rsum==tree[R(p)].len()&&a[tree[L(p)].r]<a[tree[R(p)].l])tree[p].rsum+=tree[L(p)].rsum;
       tree[p].vsum=max(tree[L(p)].vsum,tree[R(p)].vsum);
       if(a[tree[L(p)].r]<a[tree[R(p)].l])tree[p].vsum=max(tree[p].vsum,tree[L(p)].rsum+tree[R(p)].lsum);
}
void build(int p,int l,int r)
{
       tree[p].l=l;
       tree[p].r=r;
       if(l==r)
       {
              tree[p].lsum=tree[p].rsum=tree[p].vsum=1;
              return;
       }
       int m=tree[p].mid();
       build(L(p),l,m);
       build(R(p),m+1,r);
       pushup(p);
}
void update(int p,int pos,int d)
{
       if(tree[p].l==tree[p].r)
       {
              a[tree[p].l]=d;
              return;
       }
       int m=tree[p].mid();
       if(pos<=m)update(L(p),pos,d);
       else update(R(p),pos,d);
       pushup(p);
}
int query(int p,int l,int r)
{
       int ans=0;
       if(tree[p].l>=l&&tree[p].r<=r)return tree[p].vsum;
       int m=tree[p].mid();
       if(r<=m)return query(L(p),l,r);
       else if(l>m)return query(R(p),l,r);
       else
       {
             int t1=query(L(p),l,r);
             int t2=query(R(p),l,r);
             ans=max(t1,t2);
             if(a[m]<a[m+1])
             {
                    t1=min(tree[L(p)].rsum,m-l+1);
                    t2=min(tree[R(p)].lsum,r-m);
                    ans=max(ans,t1+t2);
             }
       }
       return ans;
}
int main()
{
       int i,j,k,m,n,T;
       scanf("%d",&T);
       while(T--)
       {
              scanf("%d%d",&n,&m);
              for(i=0;i<n;i++)scanf("%d",&a[i]);
              char ch[10];
              build(1,0,n-1);
             // cout<<tree[1].vsum<<endl;
              while(m--)
              {
                     scanf("%s%d%d",ch,&i,&j);
                     if(ch[0]=='U')update(1,i,j);
                     else printf("%d\n",query(1,i,j));
              }
       }
       return 0;
}

 

posted @ 2013-10-03 00:33  线性无关  阅读(129)  评论(0)    收藏  举报