A subsequence of a sequence is a sequence which is obtained by deleting zero or more elements from the sequence.
You are given a sequence A
in which every element is a pair of integers i.e A
= [(a1, w1), (a2, w2),..., (aN, wN)].
For a subseqence B
= [(b1, v1), (b2, v2), ...., (bM, vM)] of the given sequence :
Task:
Given a sequence, output the maximum weight formed by an increasing subsequence.
Input:
The first line of input contains a single integer T. T test-cases follow. The first line of each test-case contains an integer N. The next line contains a1, a2 ,... , aN separated by a single space. The next line contains w1, w2, ..., wN separated by a single space.
Output:
For each test-case output a single integer: The maximum weight of increasing subsequences of the given sequence.
Constraints:
1 <= T <= 5
1 <= N <= 150000
1 <= ai <= 109, where i ∈ [1..N]
1 <= wi <= 109, where i ∈ [1..N]
Sample Input:
2
4
1 2 3 4
10 20 30 40
8
1 2 3 4 1 2 3 4
10 20 30 40 15 15 15 50
Sample Output:
100
110
Explanation:
In the first sequence, the maximum size increasing subsequence is 4, and there's only one of them. We choose B = [(1, 10), (2, 20), (3, 30), (4, 40)]
, and we have Weight(B) = 100
.
In the second sequence, the maximum size increasing subsequence is still 4, but there are now 5 possible subsequences:
1 2 3 4
10 20 30 40
1 2 3 4
10 20 30 50
1 2 3 4
10 20 15 50
1 2 3 4
10 15 15 50
1 2 3 4
15 15 15 50
Of those, the one with the greatest weight is B = [(1, 10), (2, 20), (3, 30), (4, 50)]
, with Weight(B) = 110
.
Please note that this is not the maximum weight generated from picking the highest value element of each index. That value, 115, comes from [(1, 15), (2, 20), (3, 30), (4, 50)], which is not a valid subsequence because it cannot be created by only deleting elements in the original sequence.
题意:给定两个序列和 要求最大的第二个序列和 满足第一个序列满足递增。
解法:这题的背景应该是经典的最大上升子序列和。但考虑到那是一个O(n^2)算法。需要在这个的基础上进行优化。
解法1:维护一个单调set
有一件事可以确定,我们要是得大的数字的权值和尽可能大。这也是单调的意义所在。
如果一个数大但权值和小,我们可以不考虑这个数,因为有一个比它小的数可以添加构成更大的序列。
首先离散化,将所有的数字排序并离散化成由1开始递增的数列(用map)
用val[i]表示这个数字能构成的最大值。
然后每次插入时向后维护,移除那些不符合单调性的元素。
查找的时候进行二分。
但这样其实很慢,要1秒多。
#include
#include
#include
#include
#include
#include
#include
#include
#include
解法2:数状数组(bit)
用数状数组维护一段区间的最大值(记住了:数状数组也可以用于维护区间最大值)
读入,去重,每个数字从小到大对应为下标0、1、2.....
然后每次处理一个数,用lower_bound寻找大于等于它的第一个数,由于树状数组的下标从1开始,所以这里正好找的是前一个数
查询1-当前下标的最大值+w[i]
再更新即可。还是由于下标,要更新的是下一位。很巧妙了。
#include
#include
#include
#include
#include
#include
#include
#include
#include