现在的位置: 首页 > 综合 > 正文

SWUN OJ 1749(DP + 线段树)

2018年10月13日 ⁄ 综合 ⁄ 共 1132字 ⁄ 字号 评论关闭

SWUN 1749

题目链接

思路:lis一样的状态转移方程,不过要利用线段树去维护,每次更新到i,相应的维护i - d之后的区间的最大值,不断转移即可

代码:

#include <cstdio>
#include <cstring>
#include <algorithm>
using namespace std;

#define lson(x) ((x<<1)+1)
#define rson(x) ((x<<1)+2)

const int N = 100005;

int n, d, A[N];

struct Node {
    int l, r, v;
} node[N * 4];

void pushup(int x) {
    node[x].v = max(node[lson(x)].v, node[rson(x)].v);
}

void build(int l, int r, int x = 0) {
    int mid = (l + r) / 2;
    node[x].l = l; node[x].r = r; node[x].v = 0;
    if (l == r) {
	return;
    }
    build(l, mid, lson(x));
    build(mid + 1, r, rson(x));
    pushup(x);
}

void add(int v, int val, int x = 0) {
    if (node[x].l == node[x].r) {
	node[x].v = max(node[x].v, val);
	return;
    }
    int mid = (node[x].l + node[x].r) / 2;
    if (v <= mid) add(v, val, lson(x));
    else add(v, val, rson(x));
    pushup(x);
}

int query(int l, int r, int x = 0) {
    if (r < l) return 0;
    if (node[x].l >= l && node[x].r <= r)
	return node[x].v;
    int mid = (node[x].l + node[x].r) / 2;
    int ans = 0;
    if (l <= mid) ans = max(ans, query(l, r, lson(x)));
    if (r > mid) ans = max(ans, query(l, r, rson(x)));
    return ans;
}

int dp[N];

int main() {
    while (~scanf("%d%d", &n, &d)) {
	build(0, 100000);
	int ans = 0;
	for (int i = 1; i <= d; i++) {
	    scanf("%d", &A[i]);
	    dp[i] = 1;
	}
	for (int i = d + 1; i <= n; i++) {
	    scanf("%d", &A[i]);
	    add(A[i - d - 1], dp[i - d - 1]);
	    dp[i] = query(1, A[i] - 1) + 1;
	    ans = max(dp[i], ans);
	}
	printf("%d\n", ans);
    }
    return 0;
}

抱歉!评论已关闭.