70pts 求助
查看原帖
70pts 求助
448887
cancan123456楼主2023/8/9 19:53
#include <cstdio>
#include <algorithm>
using namespace std;
const int N = 200005;
const int mod = 1000000007;
int a[N], b[N];
int lowbit(int x) {
    return x & -x;
}
struct Result {
    int max_val, sum;
    Result() {
        max_val = sum = 0;
    }
    Result(int a, int b) {
        max_val = a;
        sum = b;
    }
};
Result operator + (const Result & a, const Result & b) {
    Result c;
    c.max_val = max(a.max_val, b.max_val);
    if (c.max_val == a.max_val) {
        c.sum += a.sum;
    }
    if (c.max_val == b.max_val) {
        c.sum += b.sum;
    }
    return c;
}
struct Node {
    int l, r;
    Result res;
} tf[4 * N], tg[4 * N];
void push_up(Node node[], int p) {
    node[p].res = node[2 * p].res + node[2 * p + 1].res;
}
void build(Node node[], int p, int l, int r) {
    node[p].l = l;
    node[p].r = r;
    if (l != r) {
        int mid = (l + r) / 2;
        build(node, 2 * p, l, mid);
        build(node, 2 * p + 1, mid + 1, r);
    }
}
void add(Node node[], int p, int pos, Result res) {
    if (node[p].l == node[p].r) {
        node[p].res = node[p].res + res;
    } else {
        int mid = (node[p].l + node[p].r) / 2;
        if (pos <= mid) {
            add(node, 2 * p, pos, res);
        } else {
            add(node, 2 * p + 1, pos, res);
        }
        push_up(node, p);
    }
}
Result query(Node node[], int p, int l, int r) {
    if (l > r) {
        return Result();
    } else if (l <= node[p].l && node[p].r <= r) {
        return node[p].res;
    } else {
        Result ans;
        int mid = (node[p].l + node[p].r) / 2;
        if (l <= mid) {
            ans = ans + query(node, 2 * p, l, r);
        }
        if (mid + 1 <= r) {
            ans = ans + query(node, 2 * p + 1, l, r);
        }
        return ans;
    }
}
int pow(int a, int b) {
    int ans = 1;
    while (b != 0) {
        if (b % 2 == 1) {
            ans = 1ll * ans * a % mod;
        }
        a = 1ll * a * a % mod;
        b = b / 2;
    }
    return ans;
}
int f[N], g[N], fnum[N], gnum[N];
int main() {
    int n;
    scanf("%d", &n);
    for (int i = 1; i <= n; i++) {
        scanf("%d", &a[i]);
        b[i] = a[i];
    }
    sort(b + 1, b + n + 1);
    int len = unique(b + 1, b + n + 1) - (b + 1);
    for (int i = 1; i <= n; i++) {
        a[i] = lower_bound(b + 1, b + len + 1, a[i]) - b;
    }
    build(tf, 1, 1, len);
    build(tg, 1, 1, len);
    for (int i = n; i >= 1; i--) {
        Result res = query(tf, 1, a[i] + 1, len);
        f[i] = res.max_val + 1;
        fnum[i] = res.sum;
        if (f[i] == 1) {
            fnum[i] = (fnum[i] + 1) % mod;
        }
        res = query(tg, 1, 1, a[i] - 1);
        g[i] = res.max_val + 1;
        gnum[i] = res.sum;
        if (g[i] == 1) {
            gnum[i] = (gnum[i] + 1) % mod;
        }
        add(tf, 1, a[i], Result(f[i], fnum[i]));
        add(tg, 1, a[i], Result(g[i], gnum[i]));
    }
    int res = 0;
    for (int i = 1; i <= n; i++) {
        res = max(res, f[i] + g[i] - 1) % mod;
    }
    int ans = 0;
    for (int i = 1; i <= n; i++) {
        if (f[i] + g[i] - 1 == res) {
            ans = (ans + 1ll * fnum[i] * gnum[i] % mod * pow(2, n - res)) % mod;
        }
    }
    printf("%d %d", res, ans);
    return 0;
}
2023/8/9 19:53
加载中...