比赛 |
2022级DP专题练习赛7 |
评测结果 |
AAAWWAAAAAAAAAAAAAAA |
题目名称 |
数列 |
最终得分 |
90 |
用户昵称 |
zxhhh |
运行时间 |
2.730 s |
代码语言 |
C++ |
内存使用 |
17.36 MiB |
提交时间 |
2023-02-27 20:59:23 |
显示代码纯文本
#include <bits/stdc++.h>
using namespace std;
const int N = 2e5 + 5, mod = 1e9 + 7;
typedef long long ll;
int s[N << 1], n, dp[N << 1], t[N << 1], ord[N << 1];
ll cnt, ans, tw[N], c[N <<1];
struct node {
int l, r, m;
ll c;
}nodes[N << 2];
inline void push_up (int p) {
nodes[p].m = max(nodes[p << 1].m, nodes[p << 1 | 1].m);
nodes[p].c = 0;
if (nodes[p << 1].m >= nodes[p].m) nodes[p].c = (nodes[p].c+nodes[p << 1].c) % mod;
if (nodes[p << 1 | 1].m >= nodes[p].m) nodes[p].c = (nodes[p].c + nodes[p << 1 | 1].c) % mod;
}
void build (int p, int l, int r) {
nodes[p].l = l, nodes[p].r = r;
if (l == r) return;
int mid = (l + r) >> 1;
build (p << 1, l, mid); build (p << 1 | 1, mid +1, r);
push_up (p);
}
void reset (int p, int idx, int m, ll c) {
if (idx == 0) return;
int tl = nodes[p].l, tr = nodes[p].r;
if (tl == tr) {
if (nodes[p].m < m) nodes[p].m = m, nodes[p].c = c;
else if (nodes[p].m == m) nodes[p].c = (nodes[p].c + c) % mod;
return;
}
int mid = (tl + tr) >> 1;
if (idx <= mid) reset (p << 1, idx, m, c);
else reset (p << 1 | 1, idx, m, c);
push_up (p);
}
node query (int p, int l, int r) {
int tl = nodes[p].l, tr = nodes[p].r;
if (tl >= l && tr <= r) return nodes[p];
int mid = (tl + tr) >> 1; node res; res.m = res.c = 0;
if (l <= mid) {
node k = query(p << 1, l, r);
if(res.m < k.m) res.m = k.m, res.c = k.c;
else if (res.m == k.m) res.c = (res.c + k.c) % mod;
}
if (r > mid) {
node k = query(p << 1 | 1, l, r);
if(res.m < k.m) res.m = k.m, res.c = k.c;
else if (res.m == k.m) res.c = (res.c + k.c) % mod;
}
return res;
}
//deque <int> q;
//vector <int> f[N];
//
//void dfs (int p) {
// if (p > n) {
//// cout <<endl;
// memset(dp, 0, sizeof(dp)); memset(c, 0, sizeof(c));
// int m = 0;
// deque <int> t = q;
// for (int i = 1;i <= n;i++) a[i] = t.front(), t.pop_front();
// for (int i = 1;i <= n;i++) {
// int x = 0;
// for (int j = 1;j < i;j++) {
// if (a[j] < a[i]) {
// if (dp[j] > x) {
// c[i] = c[j];
// x = dp[j];
// }
// else if (dp[j] == x) c[i] += c[j];
// }
// }
// dp[i] = x + 1;
// if (dp[i] == 1) c[i] = 1;
// m = max(dp[i], m);
//// cout << dp[i] << " " <<c[i] <<endl;
// }
// if (m < ans) return;
// if (m > ans) cnt = 0, ans = m;
// for (int i = 1;i <= n;i++) if (dp[i] == m) cnt += c[i], cnt %= mod;
// return;
// }
// q.push_front(s[p]); dfs(p + 1); q.pop_front();
// if (p > 1) {q.push_back(s[p]); dfs(p + 1); q.pop_back(); }
//}
//
int main () {
freopen("lisshulie.in", "r", stdin);
freopen("lisshulie.out", "w", stdout);
scanf("%d", &n);
for (int i = 1;i <= n;i++) scanf("%d", &s[i]);
reverse(s + 1, s + 1 + n);
for (int i = n + 1;i <= 2 * n;i++) s[i] = s[2 * n + 1 - i];
tw[0] = 1;
for (int i = 1;i <= n;i++) tw[i] = tw[i - 1] * 2 % mod;
for (int i = 1;i <= 2 * n;i++) t[i] = s[i];
sort(t +1, t + 1 + 2 *n);
int ss = unique (t +1, t + 1 + 2 * n) - t - 1;
for (int i = 1;i <= 2 * n;i++) ord[i] = lower_bound (t+1, t+1+ss, s[i]) - t;
build (1, 1, n);
for (int i = 1;i <= 2 * n;i++) {
node x = query(1, 1, ord[i] - 1);
dp[i] = x.m + 1;
if(dp[i] >1) c[i] = x.c;
else c[i] = 1;
reset (1, ord[i], dp[i], c[i]);
}
for (int i = 1;i <= 2 * n;i++) {
// cout << ord[i] << " " << dp[i] << " " <<c[i] << endl;
if(dp[i] > ans ) ans = dp[i], cnt = c[i];
else if (dp[i] == ans) cnt = (cnt + c[i]) % mod;
}
if (ans < n) cnt = cnt * tw[n - ans - 1] % mod;
cout << ans <<" " << cnt << endl;
// dfs(1);
// cout << ans << " " << cnt << endl;
return 0;
}