`
java-mans
  • 浏览: 11743309 次
文章分类
社区版块
存档分类
最新评论

HDU 3564 Another LIS 线段树+最长上升子序列

 
阅读更多

排队问题是线段树中很常见的题型。题目大意就是不断的向一个序列插入数据,插入的位置为当前序列的第某个位置,每次插入后都要求当前序列的最长上升子序列的长度。



/*
ID: sdj22251
PROG: subset
LANG: C++
*/
#include <iostream>
#include <vector>
#include <list>
#include <map>
#include <set>
#include <deque>
#include <queue>
#include <stack>
#include <bitset>
#include <algorithm>
#include <functional>
#include <numeric>
#include <utility>
#include <sstream>
#include <iomanip>
#include <cstdio>
#include <cmath>
#include <cstdlib>
#include <cctype>
#include <string>
#include <cstring>
#include <cmath>
#include <ctime>
#define LOCA
#define MAXN 100005
#define INF 100000000
#define eps 1e-7
#define L(x) x<<1
#define R(x) x<<1|1
using namespace std;
struct node
{
    int left, right, mid, cnt;
}tree[4 * MAXN];
int a[MAXN], pos[MAXN];
int nk[MAXN];
void make_tree(int s, int e, int C)
{
    tree[C].left = s;
    tree[C].right = e;
    tree[C].mid = ((s + e) >> 1);
    tree[C].cnt = tree[C].right - tree[C].left + 1;
    if(s == e) return;
    make_tree(s, tree[C].mid, L(C));
    make_tree(tree[C].mid + 1, e, R(C));
}
void  insert(int p, int v, int C)
{
    tree[C].cnt--;
    if(tree[C].right == tree[C].left)
    {
        pos[v] = tree[C].right;
        return;
    }
    if(tree[L(C)].cnt >= p)
    insert(p, v, L(C));
    else insert(p - tree[L(C)].cnt, v, R(C));
}
int main()
{
    int n, i;
    int T;
    scanf("%d", &T);
    int cas = 0;
    while(T--)
    {
        scanf("%d", &n);
        printf("Case #%d:\n", ++cas);
        make_tree(1, n, 1);
        for(i = 0; i < n; i++)
        {
            scanf("%d", &a[i]);
        }
        for(i = n - 1; i >= 0; i--)
        {
            insert(a[i] + 1, i + 1, 1);
        }
        int cnt = 0;
        for(i = 1; i <= n; i++)
        {
            if(cnt == 0 || pos[i] > nk[cnt]) //如果是第一个或者比队头的大,则存入数组
            nk[++cnt] = pos[i];
            else
            {
                int high = cnt;
                int low = 1;
                while(low <= high) //在已存序列中寻找位置,将输入的数替换进去,这样可以保证一直是上升序列
                {
                    int mid = (low + high) / 2;
                    if(nk[mid] < pos[i])
                    low = mid + 1;
                    else high = mid - 1;
                }
                nk[low] = pos[i];
            }
            printf("%d\n", cnt);
        }
        printf("\n");
    }
    return 0;
}
		


分享到:
评论

相关推荐

    ACM hdu 线段树题目+源代码

    ACM hdu 线段树题目+源代码 线段树是一种非常重要的数据结构,它广泛应用于算法竞赛和实际编程中。今天,我们将通过 ACM hdu 的几个题目来学习和掌握线段树的基本概念和应用。 线段树的基本概念 线段树是一种...

    hdu acm1166线段树

    hdu 1166线段树代码

    hdu 1166线段树

    标题与描述均提到了“hdu 1166线段树”,这表明文章的核心是关于线段树在解决特定问题中的应用。线段树是一种数据结构,主要用于处理区间查询和更新操作,尤其是在大规模数据集上。在本例中,通过分析给定的部分代码...

    hdu 1257 最低拦截系统 lis

    根据给定的信息,我们可以推断出这是一道与编程竞赛相关的题目,主要涉及的是最长递增子序列(Longest Increasing Subsequence,简称LIS)算法的应用。下面将详细解析题目含义、解题思路以及代码实现。 ### 题目...

    线段树完整版

    ### 线段树知识点详解 #### 一、线段树基本概念与应用 线段树是一种二叉树数据结构,常用于处理区间查询或区间更新的问题。它将一个线性序列分割成多个不连续的段,每一个节点代表一个区间,并且通过递归的方式将...

    hdu 1695 GCD(欧拉函数+容斥原理).docx

    "hdu 1695 GCD(欧拉函数+容斥原理)" 题目大意是:给定 a, b, c, d, k,找到一队 x, y,满足 g(x, y) = k,且 x ∈ [1, b], y ∈ [1, d],问有多少对符合要求的 (x, y)。 思路是:gcd(x, y) == k 解释 x, y 都能...

    线段树入门学习(兼解HDU1754)

    这篇博客“线段树入门学习(兼解HDU1754)”旨在帮助初学者理解线段树的基本概念,并通过解决HDU1754题目来实践其应用。 线段树的核心思想是将一个区间分解成多个子区间,然后对每个子区间进行预处理,存储区间的信息...

    HDU ACM as easy as a+b

    - **HDU** 指的是“杭州电子科技大学”(Hangzhou Dianzi University),这所大学在ACM国际大学生程序设计竞赛中有着优异的表现。 - **ACM** 是指“Association for Computing Machinery”,即计算机协会,而在此处...

    HDU+2000-2099+解题报告

    例如背包问题、最长公共子序列、矩阵链乘法等。 3. **图论**:包括最短路径算法(Dijkstra、Floyd-Warshall、Bellman-Ford)、最小生成树(Prim、Kruskal)、拓扑排序等。 4. **字符串处理**:如KMP算法、Manacher...

    线段树题目

    - **HDU 3308**:涉及到单点更新和查询区间最长连续上升序列长度的问题。在线段树的节点中需要建立三个域,分别是从左边起最长的连续序列、从右边起的连续序列,以及这个区间中最长的连续序列长度。 - **HDU 2781**...

    hdu 300+ AC 代码

    在编程竞赛中,动态规划常用于解决背包问题、最长公共子序列、最短路径等问题。理解动态规划的状态转移方程和边界条件是掌握这一方法的关键。 这个压缩包中的300+ AC代码提供了丰富的示例,可以帮助学习者深入理解...

    HDU+2000-2099+解题报告.zip

    1. **动态规划**:动态规划是一种用于解决最优化问题的常用方法,例如背包问题、最长公共子序列、矩阵链乘法等。解题报告会解释如何定义状态、设计状态转移方程,并给出具体代码实现。 2. **图论算法**:包括最短...

    HH神总结的线段树专辑-超经典的

    ### 线段树经典知识点解析 #### 一、线段树简介与代码风格 **线段树**是一种用于高效处理区间查询与更新操作的数据结构。它可以用来解决一系列与区间有关的问题,例如区间求和、区间最值等问题。相较于其他数据...

    hdu 3333 turing tree 解题报告

    题目“HDU 3333 Turing Tree”要求解决的问题是:给定一个整数序列和一系列区间,计算每个区间内不重复数字的和。由于数据规模较大(N ,000, K ,000),直接的暴力方法效率过低,因此我们需要采用一种更高效的数据...

    【hdu5306】Gorgeous Sequence 线段树区间最值操作-附件资源

    【hdu5306】Gorgeous Sequence 线段树区间最值操作-附件资源

    线段树入门

    线段树入门资料,有利于初学者学习,让他们详细了解线段树。

    ACM HDU题目分类

    1025 经典 DP,最长递增子序列(要用 NLogN 的方法过);1051 经典贪心,也可以用 DP;1058 经典问题,丑数,DP;1081 经典 DP 等等。 搜索题 搜索题是 ACM HDU 题目分类中的一大类,例如,1010 搜索题,剪枝很...

    HDU题目java实现

    9. **动态规划**:这是一种优化策略,通过构建状态转移方程来求解问题,例如背包问题、最长公共子序列、矩阵链乘法等。 10. **回溯法**:在解决组合优化问题和逻辑推理问题时常用,如八皇后问题、数独求解等。 11....

    hdu 3341(ac自动机+状态压缩)

    hdu 3341(ac自动机+状态压缩) 题意:容易理解... 思路:首先一开始容易想到要用到dp,开设一个dp[41][41][41][41][501]的数组来解决,但是明显内存已经超出范围了,于是就想如何减少内存呢?只要知道A、T、C、G其中...

Global site tag (gtag.js) - Google Analytics