HDU 4604 (树状数组)

来源:互联网 发布:python pyqt 实例 编辑:程序博客网 时间:2024/05/20 17:24

题目链接:点击这里

题意:给出一个序列,从头到尾依次扔进一个双端队列或者直接不要,双端队列可以在任意时刻从头或者尾弹出元素。最大化最后的双端队列size。

求出每个下标开头的最长递增序列和最长递减序列,然后扫一遍用树状数组维护即可。

#include <cstdio>#include <cstring>#include <cmath>#include <algorithm>#include <vector>#include <queue>#include <iostream>using namespace std;#define maxn 100005int dp[maxn], dp2[maxn];//以i开头的最长递增子序列 以i开头的最长递减子序列int c[maxn], a[maxn], n;vector <int> num;int gg[maxn], cnt;void lisanhua () {//离散化    sort (num.begin (), num.end ());    for (int i = 0; i < n; i++) {        if (!i || num[i] != num[i-1]) {            gg[++cnt] = num[i];        }    }    for (int i = 1; i <= n; i++) {         a[i] = lower_bound (gg+1, gg+1+cnt, a[i])-gg;    }}int lowbit (int x) {    return x&(-x);}void update1 (int pos, int num) {    for (int i = pos; i > 0; i -= lowbit (i))        c[i] = max (c[i], num);}void update2 (int pos, int num) {    for (int i = pos; i <= n; i += lowbit (i))        c[i] = max (c[i], num);}int query_max (int pos) {    int ans = 0;    for (int i = pos; i <= n; i += lowbit (i)) {        ans = max (ans, c[i]);    }    return ans;}int query_min (int pos) {    int ans = 0;    for (int i = pos; i > 0; i -= lowbit (i)) {        ans = max (ans, c[i]);    }    return ans;}void solve () {    memset (c, 0, sizeof c);    for (int i = n; i >= 1; i--) {        dp[i] = query_max (a[i])+1;        update1 (a[i], dp[i]);    }    memset (c, 0, sizeof c);    for (int i = n; i >= 1; i--) {        dp2[i] = query_min (a[i])+1;        update2 (a[i], dp2[i]);    }    int ans = 0;    for (int i = 1; i <= n; i++) {        int tmp = query_min (a[i]-1);         ans = max (ans, tmp+dp[i]);    }    printf ("%d\n", ans);}int main () {    //freopen ("more.in", "r", stdin);    int t;    scanf ("%d", &t);    while (t--) {        scanf ("%d", &n);        cnt = 0;        num.clear ();        for (int i = 1; i <= n; i++) {            scanf ("%d", &a[i]);            num.push_back (a[i]);        }        lisanhua ();        solve ();    }    return 0;}
0 0