zoukankan      html  css  js  c++  java
  • HDU 3308 线段树单点更新+区间查找最长连续子序列

                                                          LCIS

                                                                 Time Limit: 6000/2000 MS (Java/Others)    

                                                                Memory Limit: 65536/32768 K (Java/Others)
                                                                Total Submission(s): 5591    Accepted Submission(s): 2443


    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
     
    Author
    shǎ崽
     
    题解:开始看错题,以为是最长子序列,GG,
      后知后觉,线段树秒了
    ///1085422276
    #include<iostream>
    #include<cstdio>
    #include<cstring>
    #include<string>
    #include<algorithm>
    #include<queue>
    #include<cmath>
    #include<map>
    #include<bitset>
    #include<set>
    #include<vector>
    using namespace std ;
    typedef long long ll;
    #define mem(a) memset(a,0,sizeof(a))
    #define meminf(a) memset(a,127,sizeof(a))
    #define memfy(a)  memset(a,-1,sizeof(a))
    #define TS printf("111111
    ");
    #define FOR(i,a,b) for( int i=a;i<=b;i++)
    #define FORJ(i,a,b) for(int i=a;i>=b;i--)
    #define READ(a,b) scanf("%d%d",&a,&b)
    #define mod 1000000007
    #define inf 1000000001
    #define maxn 200000+2
    inline ll read()
    {
        ll x=0,f=1;
        char ch=getchar();
        while(ch<'0'||ch>'9')
        {
            if(ch=='-')f=-1;
            ch=getchar();
        }
        while(ch>='0'&&ch<='9')
        {
            x=x*10+ch-'0';
            ch=getchar();
        }
        return x*f;
    }
    //****************************************
    struct ss
    {
        int l,r,v,ans;
        int lc,rc;
    }tr[maxn<<2];
    int a[maxn<<2],n,q;
    void push_up(int k)
    {
        if(a[tr[k<<1].r]<a[tr[k<<1|1].l])
        {
            tr[k].ans=max(max(tr[k<<1].ans,tr[k<<1|1].ans),tr[k<<1].rc+tr[k<<1|1].lc);
            if(tr[k<<1].lc==(tr[k<<1].r-tr[k<<1].l+1))
            {
                tr[k].lc=tr[k<<1].lc+tr[k<<1|1].lc;
            }else  tr[k].lc=tr[k<<1].lc;
            if(tr[k<<1|1].lc==(tr[k<<1|1].r-tr[k<<1|1].l+1))
            {
                 tr[k].rc=tr[k<<1|1].rc+tr[k<<1].rc;
            }else  tr[k].rc=tr[k<<1|1].rc;
        }
        else
        {
            tr[k].ans=max(tr[k<<1].ans,tr[k<<1|1].ans);
            tr[k].lc=tr[k<<1].lc;
            tr[k].rc=tr[k<<1|1].rc;
        }
    }
    void build(int k,int s,int t)
    {
        tr[k].l=s;
        tr[k].r=t;
        if(s==t)
        {
            tr[k].v=a[s];
            tr[k].ans=1;
            tr[k].lc=1;
            tr[k].rc=1;
            return ;
        }
        int mid=(s+t)>>1;
        build(k<<1,s,mid);
        build(k<<1|1,mid+1,t);
        push_up(k);
    }
    void update(int k,int x,int c)
    {
        if(tr[k].l==x&&tr[k].r==x)
        {
            tr[k].v=c;
            a[x]=c;
            return ;
        }
        int mid=(tr[k].l+tr[k].r)>>1;
        if(x<=mid)update(k<<1,x,c);
        else update(k<<1|1,x,c);
        push_up(k);
    }
    int ask(int k,int s,int t)
    {
        if(tr[k].l==s&&tr[k].r==t)
        {
            return tr[k].ans;
        }
        int mid=(tr[k].l+tr[k].r)>>1;
        if(t<=mid)return ask(k<<1,s,t);
        else if(s>mid)return ask(k<<1|1,s,t);
        else {
          int ret=0;
          int A=ask(k<<1,s,mid);
          int B=ask(k<<1|1,mid+1,t);
          ret=max(A,B);
          A=min(tr[k<<1].rc,mid-s+1);
          B=min(tr[k<<1|1].lc,t-mid);
             if(a[tr[k<<1].r]<a[tr[k<<1|1].l])
                    ret=max(A+B,ret);
          return ret;
        }
    }
    int main()
    {
    
        int T=read();
        while(T--)
        {
            n=read();
            q=read();
            FOR(i,1,n)
            {
                a[i]=read();
            }
            build(1,1,n);
            int a,b;
            char ch[321];
            FOR(i,1,q)
            {
                scanf("%s%d%d",ch,&a,&b);
                if(ch[0]=='Q')
                {
                    printf("%d
    ",ask(1,a+1,b+1));
                }
                else update(1,a+1,b);
            }
        }
        return 0;
    }
    代码
  • 相关阅读:
    平凡人生的忠告
    Visio建模
    2007的第一天....
    PowerDesigner12对SQL2005反向工程问题.
    强人画的画:)
    2006的最后一天
    ASP.NET生成树形显示的GridView
    输出由1~9组成和三组三位数,第二组是第一组的2倍,第三组是第一组的3倍,三组数字中无重复数字
    C#读取图片Exif信息
    C#读取数据库图片显示、缩小、更新
  • 原文地址:https://www.cnblogs.com/zxhl/p/4790424.html
Copyright © 2011-2022 走看看