zoukankan      html  css  js  c++  java
  • HDU3308

    题目链接:https://vjudge.net/problem/HDU-3308

    解题思路:以len[ ]保存区间内的最长单调递增区间长度,以llen[ ]保存区间内从第一个元素开始的最长单调递增区间长度,以rlen[ ]保存区间内以最后一个元素为结尾的最长单调递增区间长度,在此基础上建立线段树。【 b( ̄▽ ̄)d 好拗口啊~】

            重点主要是在pushup()的区间合并操作和query( )的查询操作,都是在下精心策划出来的,希望看官能稍加体味,不吝赐教。

    AC代码:

    #include <iostream>
    #include <cstdio>
    #include <algorithm>
    using namespace std;
    #define lson l,m,rt<<1
    #define rson m+1,r,rt<<1|1
    const int maxn=1e5+6;
    int llen[maxn<<2],rlen[maxn<<2],len[maxn<<2],tree[maxn];
    void pushup(int l,int r,int rt){
        int m=(l+r)>>1;
        llen[rt]=llen[rt<<1];   rlen[rt]=rlen[rt<<1|1];
        if(tree[m+1]>tree[m]){
            if(llen[rt<<1]==m-l+1)   llen[rt]+=llen[rt<<1|1];
            if(rlen[rt<<1|1]==r-m)   rlen[rt]+=rlen[rt<<1];
            len[rt]=max(max(len[rt<<1],len[rt<<1|1]),rlen[rt<<1]+llen[rt<<1|1]);
        }
        else
            len[rt]=max(len[rt<<1],len[rt<<1|1]);
    }
    void build(int l,int r,int rt){
        if(l==r){
            scanf("%d",&tree[l]);
            len[rt]=llen[rt]=rlen[rt]=1;
            return;
        }
        int m=(l+r)>>1;
        build(lson);
        build(rson);
        pushup(l,r,rt);
    }
    int query(int L,int R,int l,int r,int rt){
        if(L<=l&&r<=R)
            return len[rt];
        int m=(l+r)>>1;
        if(L<=m&&m<R){
            int l1=query(L,R,lson),l2=query(L,R,rson);
            if(tree[m]<tree[m+1]){
                int le=max(L,m-rlen[rt<<1]+1),ri=min(R,m+llen[rt<<1|1]);
                return max(max(l1,l2),ri-le+1);
            }
            return max(l1,l2);
        }
        else if(R<=m)
            return query(L,R,lson);
        else
            return query(L,R,rson);
    }
    void update(int d,int c,int l,int r,int rt){
        if(d==l && d==r){
            tree[d]=c;
            return;
        }
        int m=(l+r)>>1;
        if(m>=d)
            update(d,c,lson);
        else
            update(d,c,rson);
        pushup(l,r,rt);
    }
    int main(){
        int T;
        scanf("%d
    ",&T);
        while(T--){
            int n,m;
            scanf("%d%d",&n,&m);
            build(0,n-1,1);
    
            while(m--){
                char c[3];
                int a,b;
                scanf("%s %d %d",c,&a,&b);
                if(c[0]=='Q')
                    printf("%d
    ",query(a,b,0,n-1,1));
                else
                    update(a,b,0,n-1,1);
            }
        }
        return 0;
    }
    
    “这些年我一直提醒自己一件事情,千万不要自己感动自己。大部分人看似的努力,不过是愚蠢导致的。什么熬夜看书到天亮,连续几天只睡几小时,多久没放假了,如果这些东西也值得夸耀,那么富士康流水线上任何一个人都比你努力多了。人难免天生有自怜的情绪,唯有时刻保持清醒,才能看清真正的价值在哪里。”
  • 相关阅读:
    Android内存优化4 了解java GC 垃圾回收机制2 GC执行finalize的过程
    Android内存优化3 了解java GC 垃圾回收机制1
    Android内存优化2 了解java内存分配 2
    Android内存优化1 了解java内存分配 1
    Android Parcel对象详解
    Android中Parcel的分析以及使用
    Android进阶笔记:Messenger源码详解
    Android进阶笔记:AIDL内部实现详解 (二)
    Android进阶笔记:AIDL内部实现详解 (一)
    Android开发高级进阶——多进程间通信
  • 原文地址:https://www.cnblogs.com/Blogggggg/p/7190685.html
Copyright © 2011-2022 走看看