法一:线段树
#include<bits/stdc++.h>
using namespace std;
#define lson p << 1
#define rson p << 1 | 1
#define int long long
#define pb push_back
const int maxn = 1e6 + 5, inf = 1e9 + 5;
int a[maxn], b[maxn];
int t[maxn << 2], f[maxn];
void push_up(int p){
t[p] = min(t[lson], t[rson]);
}
void build(int p, int l, int r){
if(l == r){
t[p] = inf;
return;
}
int mid = (l + r) >> 1;
build(lson, l, mid);
build(rson, mid + 1, r);
push_up(p);
}
int query(int p, int l, int r, int val){
if(l == r){
return l;
}
int mid = (l + r) >> 1;
if(t[rson] < val) return query(rson, mid + 1, r, val);
else return query(lson, l, mid, val);
}
void insert(int p, int l, int r, int pos, int val){
if(l == r){
t[p] = val;
return;
}
int mid = (l + r) >> 1;
if(pos <= mid) insert(lson, l, mid, pos, val);
else insert(rson, mid + 1, r, pos, val);
push_up(p);
}
void solve(){
int n;
cin >> n;
int pos = -1;
for(int i = 0; i < n; i++){
cin >> a[i];
// b[i] = a[i];
if(a[i] == 0) pos = i;
}
if(n == 1){
cout << 1 << '\n';
return;
}
int m = 0;
pos = (pos + 1) % n;
for(int i = 0; i < n - 1; i++){
b[++m] = a[(pos + i) % n];
}
for(int i = 1; i < n; i++){
a[i] = b[i];//a数组存从0开始往右的序列
}
n--;
build(1, 1, n);
f[1] = a[1];//一开始0在排列最右边,答案为0(忽略最右边的mex值,始终为n + 1)
//f[i]表示0往左移动i次的序列mex值之和
insert(1, 1, n, 1, a[1]);
for(int i = 2; i <= n; i++){
int pos = -1;
if(t[1] > a[i]){
f[i] = i * a[i];//位置i(即1~i)的mex值取决于a数组[i+1, n]的后缀最小值
}
else{
pos = query(1, 1, n, a[i]);//找到从右往左第一个小于a[i]的位置,那么[pos+1, i]的mex都为a[i]
f[i] = f[pos] + a[i] * (i - pos);
}
insert(1, 1, n, i, a[i]);
}
int res = 0;
for(int i = 1; i <= n; i++){
res = max(res, f[i] + n + 1);
}
cout << res << '\n';
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
int T;
cin >> T;
while(T--){
solve();
}
return 0;
}
法二:
#include <bits/stdc++.h>
#define int long long
using namespace std;
int32_t main()
{
cin.tie(nullptr)->sync_with_stdio(false);
int q;
cin >> q;
while (q--)
{
int n;
cin >> n;
vector<int> a(n + 1);
for (int i = 1; i <= n; ++i)
{
cin >> a[i];
}
deque<pair<int, int>> dq;
vector<int> f(n + 1);
int mex = 0;
int sum = 0;
for (int i = 1; i <= n; ++i)
{
f[a[i]]++;
while (f[mex])
{
mex++;
}
dq.push_back({mex, 1});
sum += mex;
}
int ans = sum;
for (int i = 1; i < n; ++i)
{
pair<int, int> me = {a[i], 0};
sum -= dq.front().first;
dq.front().second--;
if (dq.front().second == 0)
{
dq.pop_front();
}
while (!dq.empty() && dq.back().first >= a[i])
{
sum -= dq.back().first * dq.back().second;
me.second += dq.back().second;
dq.pop_back();
}
dq.push_back(me);
sum = sum + me.first * me.second;
dq.push_back({n, 1});
sum += n;
ans = max(ans, sum);
}
cout << ans << '\n';
}
}