zoukankan      html  css  js  c++  java
  • hdu 3308 LCIS(线段树区间合并)

    题目链接:http://acm.hdu.edu.cn/showproblem.php?

    pid=3308

    LCIS

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


    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ǎ崽
     

    Source
     

    Recommend
    wxl   |   We have carefully selected several similar problems for you:  3397 1542 1828 2871 1255 
     

    题目大意:给n个数,m个操作。两种操作:Q a b 表示查询【a。b】这个区间的LCIS(即最长连续递增子序列)的长度。U a b 表示更新第a个数把他变成b(从0開始)。


    解题思路:主要解决简单的单点更新和区间的查询,区间记录最长的连续递增子序列长度。要分析清楚各种情况。

    详见代码。
    #include <iostream>
    #include <cstdio>
    
    using namespace std;
    
    struct node
    {
        int l,r;
        int mmax;
        int lmax,rmax;
        int lnum,rnum;
    }s[100000*4+10];
    
    void InitTree(int l,int r,int k)
    {
        s[k].l=l;
        s[k].r=r;
        s[k].mmax=1;
        s[k].rmax=1;
        s[k].lmax=1;
        s[k].lnum=s[k].rnum=0;
        if (l==r)
            return ;
        int mid=(l+r)/2;
        InitTree(l,mid,2*k);
        InitTree(mid+1,r,2*k+1);
    }
    
    void UpdataTree(int i,int change,int k)
    {
        if (s[k].l==s[k].r&&s[k].l==i)
        {
            s[k].lnum=s[k].rnum=change;
            return ;
        }
        int mid=(s[k].l+s[k].r)/2;
        if (i>mid)
            UpdataTree(i,change,2*k+1);
        else if (i<=mid)
            UpdataTree(i,change,2*k);
    
        s[k].lnum=s[k*2].lnum;
        s[k].rnum=s[k*2+1].rnum;
    
        s[k].lmax=s[k*2].lmax;
        s[k].rmax=s[k*2+1].rmax;
    
        s[k].mmax=max(s[k*2].mmax,s[k*2+1].mmax);
        if(s[k*2].rnum<s[k*2+1].lnum)
        {
            s[k].mmax=max(s[k].mmax,s[k*2].rmax+s[k*2+1].lmax);
            if(s[k*2].lmax==s[k*2].r-s[k*2].l+1)
                s[k].lmax=s[k*2].lmax+s[k*2+1].lmax;
            if(s[k*2+1].rmax==s[k*2+1].r-s[k*2+1].l+1)
                s[k].rmax=s[k*2].rmax+s[k*2+1].rmax;
        }
    }
    
    int SearchTree(int l,int r,int k)
    {
        if (s[k].l==l&&s[k].r==r)
            return s[k].mmax;
        else
        {
            int mid=(s[k].l+s[k].r)/2;
            if (l>mid)
                return SearchTree(l,r,2*k+1);
            else if (r<=mid)
                return SearchTree(l,r,2*k);
            /*else
            {
                if (s[k].lnum<s[k].rnum)
                    return SearchTree(l,mid,2*k)+SearchTree(mid+1,r,2*k+1);
                else if
            }*/
            else
            {
                int a=min(s[k*2].rmax,mid-l+1);
                int b=min(s[k*2+1].lmax,r-mid);
                int Max=max(a,b);
                Max=max(Max,SearchTree(l,mid,2*k));
                Max=max(Max,SearchTree(mid+1,r,2*k+1));
                if(s[k*2].rnum<s[2*k+1].lnum)
                {
                    Max=max(Max,a+b);
                }
                return Max;
            }
    
        }
    }
    
    int main()
    {
        int t;
        char ch[70];
        scanf("%d",&t);
        while (t--)
        {
            int n,m,w,a,b;
            scanf("%d%d",&n,&m);
            InitTree(0,n-1,1);
            for (int i=0; i<n; i++)
            {
                scanf("%d",&w);
                UpdataTree(i,w,1);
            }
            for (int i=0; i<m; i++)
            {
                //getchar();
                scanf("%s%d%d",ch,&a,&b);
                if (ch[0]=='Q')
                {
                    //cout<<"!!!!!!!!!!!!!!!!!"<<endl;
                    int ans=SearchTree(a,b,1);
                    printf ("%d
    ",ans);
    
                }
                else if (ch[0]=='U')
                {
                    UpdataTree(a,b,1);
                }
            }
        }
        return 0;
    }
    



  • 相关阅读:
    字符串匹配算法之SimHash算法
    Shell 判断
    剑指offer 面试题6:重建二叉树
    字符串匹配算法之BF(Brute-Force)算法
    Python变量/运算符/函数/模块/string
    trie树
    AWK文本处理工具(Linux)
    Linux 进程间通信(一)
    Nginx学习笔记(八) Nginx进程启动分析
    进程状态转换、CPU调度算法
  • 原文地址:https://www.cnblogs.com/yjbjingcha/p/8406058.html
Copyright © 2011-2022 走看看