题解:CF2101C 23 Kingdom
Claire0918 · · 题解
我们注意到对于一种数,仅有最左侧的和最右侧的有贡献,故考虑选择
答案为
如何选取
时间复杂度
Code:
#include<bits/stdc++.h>
#define mem(a, v) memset(a, v, sizeof(a))
using namespace std;
const int maxn = 2e5 + 10;
int t, n;
int a[maxn];
namespace DSU{
int fa[maxn];
inline int getf(int x){
return fa[x] == x ? x : fa[x] = getf(fa[x]);
}
}
using namespace DSU;
inline pair<int, long long> calc(int x, bool op){
iota(fa, fa + x + 1, 0);
long long sum = 0;
for (int i = op ? 1 : n; op ? i <= n : i; op ? i++ : i--){
const int v = min(a[i], x), p = getf(v);
p && (fa[p] = p - 1, sum += i);
if (!getf(x)){
return make_pair(i, sum);
}
}
return make_pair(-1, -1);
}
int main(){
scanf("%d", &t);
while (t--){
scanf("%d", &n);
for (int i = 1; i <= n; i++){
scanf("%d", &a[i]);
}
int l = 0, r = n;
while (l < r){
const int mid = l + r + 1 >> 1, v1 = calc(mid, true).first, v2 = calc(mid, false).first;
if (~v1 && ~v2 && v1 < v2){
l = mid;
}else{
r = mid - 1;
}
}
printf("%lld\n", calc(l, false).second - calc(l, true).second);
}
return 0;
}