QOJ.ac

QOJ

ID题目提交者结果用时内存语言文件大小提交时间测评时间
#770168#9742. 优秀的拆分SymmetreeRE 18ms14156kbC++202.2kb2024-11-21 20:58:052024-11-21 20:58:06

Judging History

你现在查看的是最新测评结果

  • [2024-11-21 20:58:06]
  • 评测
  • 测评结果:RE
  • 用时:18ms
  • 内存:14156kb
  • [2024-11-21 20:58:05]
  • 提交

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(num >= 0), assert(numi * numd >= 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: 14152kb

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: 0
Accepted
time: 18ms
memory: 14156kb

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...

result:

ok 20000 lines

Test #3:

score: -100
Runtime Error

input:

20
895
97 29 511 535 178 149 710 846 37 191 684 504 309 528 524 189 659 42 337 688 213 343 859 433 606 445 693 608 232 585 577 313 759 746 612 341 480 875 610 222 28 637 11 91 796 261 296 333 377 871 275 552 788 371 763 862 522 322 447 126 492 694 799 620 842 394 434 706 460 479 240 241 676 502 749 ...

output:


result: