#include <iostream>
#include <vector>
#include <algorithm>
using namespace std;
struct Node {
int left, right, cnt;
Node() : left(-1), right(-1), cnt(0) {}
};
vector<Node> tree;
vector<int> roots;
int get_cnt(int node) {
return (node == -1) ? 0 : tree[node].cnt;
}
int build(int l, int r) {
int node = tree.size();
tree.emplace_back();
if (l == r) {
tree[node].left = -1;
tree[node].right = -1;
tree[node].cnt = 0;
return node;
}
int mid = (l + r) / 2;
int left_child = build(l, mid);
int right_child = build(mid + 1, r);
tree[node].left = left_child;
tree[node].right = right_child;
tree[node].cnt = get_cnt(left_child) + get_cnt(right_child);
return node;
}
int update(int prev, int l, int r, int val) {
int node = tree.size();
tree.push_back({}); // 新建一个空节点
tree[node] = tree[prev]; // 复制父节点内容
if (l == r) {
tree[node].cnt++;
return node;
}
int mid = (l + r) / 2;
if (val <= mid) {
int new_left = update(tree[prev].left, l, mid, val);
tree[node].left = new_left; // 只更新左子树
} else {
int new_right = update(tree[prev].right, mid + 1, r, val);
tree[node].right = new_right; // 只更新右子树
}
tree[node].cnt = get_cnt(tree[node].left) + get_cnt(tree[node].right);
return node;
}
int query(int node_l, int node_r, int l, int r, int x) {
if (node_r == -1) return 0;
if (r <= x) {
return get_cnt(node_r) - get_cnt(node_l);
}
int mid = (l + r) / 2;
int res = 0;
res += query(tree[node_l].left, tree[node_r].left, l, mid, x);
if (x > mid) {
res += query(tree[node_l].right, tree[node_r].right, mid + 1, r, x);
}
return res;
}
vector<int> discretize(const vector<int>& a) {
vector<int> b = a;
sort(b.begin(), b.end());
b.erase(unique(b.begin(), b.end()), b.end());
vector<int> res(a.size());
for (int i = 0; i < a.size(); ++i) {
res[i] = lower_bound(b.begin(), b.end(), a[i]) - b.begin() + 1;
}
return res;
}
int get_max_disc(const vector<int>& a, int target, const vector<int>& disc) {
if (target <= *min_element(a.begin(), a.end())) return 0;
vector<int> less_vals;
for (int val : a) if (val < target) less_vals.push_back(val);
int max_less = *max_element(less_vals.begin(), less_vals.end());
for (int i = 0; i < a.size(); ++i) if (a[i] == max_less) return disc[i];
return 0;
}
int main() {
ios::sync_with_stdio(false);
cin.tie(nullptr);
int T;
cin >> T;
while (T--) {
int n;
cin >> n;
vector<int> a(n);
for (int i = 0; i < n; ++i) cin >> a[i];
if (n == 0) {
cout << 0 << '\n';
continue;
}
vector<int> disc = discretize(a);
int m = *max_element(disc.begin(), disc.end());
tree.clear();
roots.clear();
roots.push_back(build(1, m));
for (int d : disc) {
roots.push_back(update(roots.back(), 1, m, d));
}
int max_len = 1;
for (int l = 0; l < n; ++l) {
for (int r = l + 1; r < n; ++r) {
int min_val = min(a[l], a[r]);
int left = l + 1;
int right = r - 1;
int cnt = 0;
if (left <= right) {
int max_disc_val = get_max_disc(a, min_val, disc);
cnt = query(roots[left], roots[right + 1], 1, m, max_disc_val);
}
int current_len = cnt + 2;
max_len = max(max_len, current_len);
}
}
cout << max_len << '\n';
tree.shrink_to_fit();
roots.shrink_to_fit();
}
return 0;
}
为我生成java代码