洛谷 P3774 [CTSC2017] 最长上升子序列

一、python 

import bisect

def longest_increasing_subsequence_length(B, m, k):
    if m == 0:
        return 0
    
    dp = [float('inf')] * (m + 1)
    dp[0] = -float('inf')  # dp[0] is a placeholder
    
    for i in range(m):
        idx = bisect.bisect_left(dp, B[i])
        dp[idx] = B[i]
    
    # Find the length of the longest subsequence <= k
    for length in range(m, -1, -1):
        if dp[length] != float('inf'):
            if length <= k:
                return length
    return 0

# Reading input
n, q = map(int, input().split())
B = list(map(int, input().split()))

queries = []
for _ in range(q):
    m, k = map(int, input().split())
    queries.append((m, k))

# Processing each query
results = []
for m, k in queries:
    results.append(longest_increasing_subsequence_length(B[:m], m, k))

# Output results
for result in results:
    print(result)

二、c++

 

#include<bits/stdc++.h>
using namespace std;
const int N = 50000 + 5, M = 233;
inline int lowbit (int u) {return u & (-u);}
int tree[N];
inline void add (int u, int v) {while (u <= N - 5) tree[u] += v, u += lowbit (u);}
inline int query (int u) {int res = 0; while (u) res += tree[u], u -= lowbit (u); return res;}
struct Q {int m, k, id, ans;}qq[N << 2];
int sz, n, b[N], q;
struct Matrix {
	int info[M][N], sign;
	inline void insert (int u, int v, int p) {
		if (u > sz) {return ;}
		int l = 1, r = min (v, info[u][0] + 1), mid;
		while (l < r) {
			mid = (l + r) / 2;
			if (sign ^ (info[u][mid] < p)) {r = mid;}
			else {l = mid + 1;}
		}
		swap (info[u][l], p);
		info[u][0] = max (info[u][0], l);
		if (p) {insert (u + 1, l, p);}
		else {
			if (sign) {if (l > sz)add (l, 1);}
			else {add (u, 1);}
		}
	}
}m1, m2;
int main () {
	m1.sign = 0, m2.sign = 1;
	scanf ("%d%d", &n, &q);sz = sqrt (n);
	for (int i = 1; i <= n; ++i) {scanf ("%d", &b[i]);}
	for (int i = 1; i <= q; ++i) {scanf ("%d%d", &qq[i].m, &qq[i].k);qq[i].id = i;}
	sort (qq + 1, qq + q + 1, [](Q a, Q b){return a.m < b.m;});
	int pre = 0;
	for (int i = 1; i <= q; ++i) {
		while (pre < qq[i].m) {
			++pre;
			m1.insert (1, INT_MAX, b[pre]);
			m2.insert (1, INT_MAX, b[pre]);
		}
		qq[i].ans = query (qq[i].k);
	}
	sort (qq + 1, qq + q + 1, [](Q a, Q b){return a.id < b.id;});
	for (int i = 1; i <= q; ++i) {printf ("%d\n", qq[i].ans);}
	return 0;
}

链接:[CTSC2017] 最长上升子序列 - 洛谷 

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值