排队问题是线段树中很常见的题型。题目大意就是不断的向一个序列插入数据,插入的位置为当前序列的第某个位置,每次插入后都要求当前序列的最长上升子序列的长度。
/*
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 的几个题目来学习和掌握线段树的基本概念和应用。 线段树的基本概念 线段树是一种...
hdu 1166线段树代码
标题与描述均提到了“hdu 1166线段树”,这表明文章的核心是关于线段树在解决特定问题中的应用。线段树是一种数据结构,主要用于处理区间查询和更新操作,尤其是在大规模数据集上。在本例中,通过分析给定的部分代码...
根据给定的信息,我们可以推断出这是一道与编程竞赛相关的题目,主要涉及的是最长递增子序列(Longest Increasing Subsequence,简称LIS)算法的应用。下面将详细解析题目含义、解题思路以及代码实现。 ### 题目...
### 线段树知识点详解 #### 一、线段树基本概念与应用 线段树是一种二叉树数据结构,常用于处理区间查询或区间更新的问题。它将一个线性序列分割成多个不连续的段,每一个节点代表一个区间,并且通过递归的方式将...
"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题目来实践其应用。 线段树的核心思想是将一个区间分解成多个子区间,然后对每个子区间进行预处理,存储区间的信息...
- **HDU** 指的是“杭州电子科技大学”(Hangzhou Dianzi University),这所大学在ACM国际大学生程序设计竞赛中有着优异的表现。 - **ACM** 是指“Association for Computing Machinery”,即计算机协会,而在此处...
例如背包问题、最长公共子序列、矩阵链乘法等。 3. **图论**:包括最短路径算法(Dijkstra、Floyd-Warshall、Bellman-Ford)、最小生成树(Prim、Kruskal)、拓扑排序等。 4. **字符串处理**:如KMP算法、Manacher...
- **HDU 3308**:涉及到单点更新和查询区间最长连续上升序列长度的问题。在线段树的节点中需要建立三个域,分别是从左边起最长的连续序列、从右边起的连续序列,以及这个区间中最长的连续序列长度。 - **HDU 2781**...
在编程竞赛中,动态规划常用于解决背包问题、最长公共子序列、最短路径等问题。理解动态规划的状态转移方程和边界条件是掌握这一方法的关键。 这个压缩包中的300+ AC代码提供了丰富的示例,可以帮助学习者深入理解...
1. **动态规划**:动态规划是一种用于解决最优化问题的常用方法,例如背包问题、最长公共子序列、矩阵链乘法等。解题报告会解释如何定义状态、设计状态转移方程,并给出具体代码实现。 2. **图论算法**:包括最短...
### 线段树经典知识点解析 #### 一、线段树简介与代码风格 **线段树**是一种用于高效处理区间查询与更新操作的数据结构。它可以用来解决一系列与区间有关的问题,例如区间求和、区间最值等问题。相较于其他数据...
题目“HDU 3333 Turing Tree”要求解决的问题是:给定一个整数序列和一系列区间,计算每个区间内不重复数字的和。由于数据规模较大(N ,000, K ,000),直接的暴力方法效率过低,因此我们需要采用一种更高效的数据...
【hdu5306】Gorgeous Sequence 线段树区间最值操作-附件资源
线段树入门资料,有利于初学者学习,让他们详细了解线段树。
1025 经典 DP,最长递增子序列(要用 NLogN 的方法过);1051 经典贪心,也可以用 DP;1058 经典问题,丑数,DP;1081 经典 DP 等等。 搜索题 搜索题是 ACM HDU 题目分类中的一大类,例如,1010 搜索题,剪枝很...
9. **动态规划**:这是一种优化策略,通过构建状态转移方程来求解问题,例如背包问题、最长公共子序列、矩阵链乘法等。 10. **回溯法**:在解决组合优化问题和逻辑推理问题时常用,如八皇后问题、数独求解等。 11....
hdu 3341(ac自动机+状态压缩) 题意:容易理解... 思路:首先一开始容易想到要用到dp,开设一个dp[41][41][41][41][501]的数组来解决,但是明显内存已经超出范围了,于是就想如何减少内存呢?只要知道A、T、C、G其中...