zoukankan      html  css  js  c++  java
  • 51nod 1376 最长递增子序列的数量(不是dp哦,线段树 +  思维)

    题目链接:https://www.51nod.com/onlineJudge/questionCode.html#!problemId=1376

    题解:显然这题暴力的方法很容易想到就是以每个数为结尾最长的有多少个,但是这样显然会超时所以要想一个方法去优化,要么用stl要么就是数据结构

    线段树是个可以考虑的对象因为这也是求区间的和于是稍微将原数组优化一下,按照大小排序一下然后再按照下标更新这样能确保有序。具体看一下代码

    还有一点要提一下有时候要考虑两维的东西可以适当排一下序使其变成一维有序这样就方便很多了。

    #include <iostream>
    #include <cstring>
    #include <cstdio>
    #include <algorithm>
    #define mod 1000000007
    using namespace std;
    const int M = 5e4 + 10;
    typedef long long ll;
    struct node {
        int id , val;
    }a[M];
    struct TnT {
        int l , r;
        ll num;
        int Max;
    }T[M << 2];
    void push_up(int i) {
        T[i].Max = max(T[i << 1].Max , T[(i << 1) | 1].Max);
        if(T[i << 1].Max == T[(i << 1) | 1].Max) {
            T[i].num = T[i << 1].num % mod + T[(i << 1) | 1].num % mod;
        }
        else {
            if(T[i << 1].Max > T[(i << 1) | 1].Max) T[i].num = T[i << 1].num % mod;
            else T[i].num = T[(i << 1) | 1].num % mod;
        }
        T[i].num %= mod;
    }
    void build(int l , int r , int i) {
        int mid = (l + r) >> 1;
        T[i].l = l , T[i].r = r , T[i].num = 0 , T[i].Max = 0;
        if(l == r) return ;
        build(l , mid , i << 1);
        build(mid + 1 , r , (i << 1) | 1);
        push_up(i);
    }
    void update(int pos , int i , int Max , ll num) {
        int mid = (T[i].l + T[i].r) >> 1;
        if(T[i].l == T[i].r && T[i].l == pos) {
            T[i].Max = Max ,T[i].num = num % mod;
            return ;
        }
        if(mid < pos) update(pos , (i << 1) | 1 , Max , num);
        else update(pos , i << 1 , Max , num);
        push_up(i);
    }
    TnT query(int l , int r , int i) {
        int mid = (T[i].l + T[i].r) >> 1;
        if(T[i].l == l && T[i].r == r) {
            return T[i];
        }
        push_up(i);
        TnT resl , resr , res;
        if(mid < l) return query(l , r , (i << 1) | 1);
        else if(mid >= r) return query(l , r , i << 1);
        else {
            resl = query(l , mid , i << 1);
            resr = query(mid + 1 , r , (i << 1) | 1);
            if(resl.Max == resr.Max) {
                res.Max = resl.Max , res.num = resl.num % mod + resr.num % mod;
            }
            else {
                if(resl.Max > resr.Max) res.Max = resl.Max , res.num = resl.num % mod;
                else res.Max = resr.Max , res.num = resr.num % mod;
            }
            res.num %= mod;
            return res;
        }
    }
    bool cmp(node x , node y) {
        if(x.val == y.val) return x.id > y.id;
        return x.val < y.val;
    }
    int main() {
        int n;
        scanf("%d" , &n);
        for(int i = 1 ; i <= n ; i++) scanf("%d" , &a[i].val) , a[i].id = i;
        sort(a + 1 , a + 1 + n , cmp);
        build(1 , n , 1);
        for(int i = 1 ; i <= n ; i++) {
            TnT gg = query(1 , a[i].id , 1);
            update(a[i].id , 1 , gg.Max + 1 , max((ll)1 ,gg.num % mod));
        }
        printf("%lld
    " , (T[1].num + mod) % mod);
        return 0;
    }
    
  • 相关阅读:
    java + jni + mingw实例开发(基于命令行窗口模式)
    OpenCv for Android
    Android图像处理实例教程
    eclipse使用技巧
    Android NDK开发实例教程
    Android开发的教程和资源
    JAVA安装,环境变量配置
    一些比较好的博客
    uwsgi启动Django项目时:unable to load app 0 (mountpoint='') (callable not found or import error) *** no app loaded. going in full dynamic mode ***
    robot中使用evaluate转化数据格式
  • 原文地址:https://www.cnblogs.com/TnT2333333/p/7109977.html
Copyright © 2011-2022 走看看