• HDU3308(LCIS) 线段树好题


    题目链接:传送门

    题目大意:给你n个数,m个操作。操作有两种:1.U x y 将数组第x位变为y   2. Q x y 问数组第x位到第y位连续最长子序列的长度。对于每次询问,输出一个答案

    题目思路:线段树单点修改区间合并

         这道题题目好在对pushup的理解,我们在向上更新的时候有注意情况的区分

         1.如果左区间的最右边的值小于右区间最左边的值,则有一个待定答案是左儿子的右区间+右儿子的左区间

         2.如果不符合第一个条件,则有一个待定答案是左区间最大值和右区间最大值中较大的那一个。

         有一点要特别注意:如果当前区间中所有的值都符合上升序列,那么更新它的父节点时,它可以加上其他区间的边界值而进行扩充

    #include <iostream>
    #include <cstdio>
    #include <cstdlib>
    #include <cmath>
    #include <algorithm>
    #include <cstring>
    #include <stack>
    #include <cctype>
    #include <queue>
    #include <string>
    #include <vector>
    #include <set>
    #include <map>
    #include <climits>
    #define lson rt<<1,l,mid
    #define rson rt<<1|1,mid+1,r
    #define fi first
    #define se second
    #define ping(x,y) ((x-y)*(x-y))
    #define mst(x,y) memset(x,y,sizeof(x))
    #define mcp(x,y) memcpy(x,y,sizeof(y))
    using namespace std;
    #define gamma 0.5772156649015328606065120
    #define MOD 1000000007
    #define inf 0x3f3f3f3f
    #define N 100005
    #define maxn 50005
    typedef pair<int,int> PII;
    typedef long long LL;
    const double pi=acos(-1.0);
    const double e=2.718281828459;
    
    int n,m,k,x,y;
    int no[N<<2],ls[N<<2],rs[N<<2];
    int a[N];
    inline void pushup(int rt,int l,int r){
        int mid=l+r>>1;
        ls[rt]=ls[rt<<1];rs[rt]=rs[rt<<1|1];
        no[rt]=max(no[rt<<1],no[rt<<1|1]);
        if(a[mid]<a[mid+1]){
            if(ls[rt]==mid-l+1)ls[rt]+=ls[rt<<1|1];
            if(rs[rt]==r-mid)rs[rt]+=rs[rt<<1];
            no[rt]=max(no[rt],ls[rt<<1|1]+rs[rt<<1]);
        }
    }
    void build(int rt,int l,int r){
        if(l==r){
            no[rt]=ls[rt]=rs[rt]=1;
            return;
        }
        int mid=l+r>>1;
        build(lson);build(rson);
        pushup(rt,l,r);
    }
    void add(int rt,int l,int r){
        if(l==r){return;}
        int mid=l+r>>1;
        if(x<=mid)add(lson);
        else add(rson);
        pushup(rt,l,r);
    }
    int query(int rt,int l,int r){
        if(x<=l&&r<=y)return no[rt];
        int mid=l+r>>1;
        if(y<=mid)return query(lson);
        if(x>mid)return query(rson);
        int t1=query(lson);
        int t2=query(rson);
        int ans=max(t1,t2);
        if(a[mid]<a[mid+1]){
            ans=max(ans,(min(ls[rt<<1|1],y-mid)+min(rs[rt<<1],mid+1-x)));
        }
        return ans;
    }
    int main(){
        int i,j,group;
        scanf("%d",&group);
        while(group--){
            char str[5];
            scanf("%d%d",&n,&m);
            for(i=1;i<=n;++i)scanf("%d",&a[i]);
            build(1,1,n);
            while(m--){
                scanf("%s%d%d",str,&x,&y);
                ++x;
                if(str[0]=='U'){a[x]=y;add(1,1,n);}
                else{++y;printf("%d
    ",query(1,1,n));}
            }
        }
        return 0;
    }
  • 相关阅读:
    HDU2897( 巴什博奕变形)
    HTML小知识点积累
    几种自己主动运行js代码的方式
    leetcode笔记:Contains Duplicate
    【Nutch基础教程之七】Nutch的2种执行模式:local及deploy
    为什么使用模板
    前端编程提高之旅(十)----表单验证插件与cookie插件
    【HDOJ 5399】Too Simple
    进程间通信之-信号signal--linux内核剖析(九)
    iOS类的合理设计,面向对象思想
  • 原文地址:https://www.cnblogs.com/Kurokey/p/5599025.html
Copyright © 2020-2023  润新知