QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#770027 | #9742. 优秀的拆分 | Symmetree | RE | 0ms | 14180kb | C++20 | 2.2kb | 2024-11-21 20:19:59 | 2024-11-21 20:20:04 |
Judging History
answer
#include<bits/stdc++.h>
// f[i] = max(f[j]) + 1
const int N = 2e5+5;
using i64 = long long;
using i128 = __int128;
int n, c[N], p[N], f[2][N], g[2][N]; i64 d[N], cntf[2][N], cntg[2][N];
void add(int x, int k, i64 cnt) {
for(; x <= n; x += x&-x) {
if(c[x] < k) c[x] = k, d[x] = cnt;
else if(c[x] == k) d[x] += cnt;
}
}
int ask1(int x) {
int ans = 0;
for(; x; x -= x&-x) ans = std::max(ans, c[x]);
return ans;
}
i64 ask2(int x) {
i64 ans = 1; int now = 0;
for(; x; x -= x&-x) {
if(now < c[x]) ans = d[x], now = c[x];
else if(now == c[x]) ans += d[x];
}
return ans;
}
void calc(int f[], i64 cntf[]) {
for(int i = 1; i <= n; ++i) c[i] = d[i] = 0;
for(int i = 1; i <= n; ++i) {
f[i] = ask1(p[i]) + 1;
cntf[i] = ask2(p[i]);
add(p[i], f[i], cntf[i]);
}
}
void solve() {
scanf("%d", &n);
for(int i = 1; i <= n; ++i) scanf("%d", &p[i]);
// for(int i = 1; i <= n; ++i) printf("%d %lld\n", c[i], d[i]);
// for(int i = 1 ; i <= n; ++i) printf("%d %lld\n", f[0][i], cntf[0][i]);
calc(f[0], cntf[0]);
std::reverse(p + 1, p + n + 1);
calc(g[1], cntg[1]);
std::reverse(g[1] + 1, g[1] + n + 1);
std::reverse(cntg[1] + 1, cntg[1] + n + 1);
for(int i = 1; i <= n; ++i) p[i] = n + 1 - p[i];
calc(f[1], cntf[1]);
std::reverse(f[1] + 1, f[1] + n + 1);
std::reverse(cntf[1] + 1, cntf[1] + n + 1);
std::reverse(p + 1, p + n + 1);
calc(g[0], cntg[0]);
// for(int i = 1; i <= n; ++i) printf("%d %lld %d %lld\n", f[0][i], cntf[0][i], f[1][i], cntf[1][i]);
// puts("");
// for(int i = 1; i <= n; ++i) printf("%d %lld %d %lld\n", g[0][i], cntg[0][i], g[1][i], cntg[1][i]);
int LIS = 0, LDS = 0;
for(int i = 1; i <= n; ++i) {
LIS = std::max(LIS, f[0][i]);
LDS = std::max(LDS, g[0][i]);
}
i64 numi = 0, numd = 0, num = 0;
for(int i = 1; i <= n; ++i) {
if(f[0][i] == LIS) numi += cntf[0][i];
if(g[0][i] == LDS) numd += cntg[0][i];
if(f[0][i] + f[1][i] - 1 == LIS && g[0][i] + g[1][i] - 1 == LDS) {
num += cntf[0][i] * cntf[1][i] * cntg[0][i] * cntg[1][i];
}
}
assert(numi > 0), assert(numd > 0), assert(num > 0);
if(numi * numd == num) printf("%d\n", LIS + LDS - 1);
else printf("%d\n", LIS + LDS);
}
signed main() {
int t;
scanf("%d", &t);
while(t--) solve();
return 0;
}
详细
Test #1:
score: 100
Accepted
time: 0ms
memory: 14180kb
input:
3 5 3 5 1 4 2 4 1 2 4 3 5 3 5 2 1 4
output:
4 4 5
result:
ok 3 lines
Test #2:
score: -100
Runtime Error
input:
20000 2 2 1 10 6 10 2 7 9 3 8 4 1 5 9 3 6 4 5 8 9 2 7 1 7 3 7 6 4 1 5 2 7 7 2 3 6 5 1 4 5 4 1 3 2 5 9 6 7 5 3 8 1 9 2 4 3 1 2 3 8 7 2 4 6 1 8 3 5 7 4 2 6 3 1 7 5 8 1 7 3 4 2 5 6 8 2 1 2 10 10 2 3 8 6 9 1 4 7 5 4 3 2 1 4 9 7 5 3 4 1 2 9 6 8 7 2 4 5 1 6 7 3 10 3 1 10 4 9 5 6 8 2 7 5 1 2 5 3 4 6 2 6 5 ...
output:
2 8 8 6 7 5 7 3 6 6 8 2 8 4 7 6 9 5 6 7 7 8 9 7 8 1 5 6 5 7 3 3 4 3 6 7 6 1 6 5 1 8 6 8 6 6 2 3 2 6 8 5 6 5 7 3 2 7 7 6 3 1 3 1 8 7 8 4 1 1 8 7 7 2 7 2 1 9 2 5 6 3 5 6 8 6 2 2 1 6 6 7 8 3 1 8 6 10 2 8 8 4 6 3 8 8 2 4 1 3 5 8 9 1 7 7 2 6 7 4 8 1 2 5 3 1 8 6 7 1 9 7 5 7 3 8 1 5 5 6 4 5 4 1 6 2 7 6 1 7...