A(见F)
代码
#include <bits/stdc++.h>
using namespace std;
#define LL long long
#define pb push_back
#define x first
#define y second
#define endl '\n'
const LL maxn = 4e05+7;
#define int long long
const LL N = 5e05+10;
const LL mod = 1e09+7;
const int inf = 0x3f3f3f3f;
const LL llinf = 5e18;
typedef pair<int,int>pl;
priority_queue<LL , vector<LL>, greater<LL> >mi;
priority_queue<LL> ma;
struct DSU {
std::vector<int> f, siz , cnt0 , cnt1 , tag , val;
int cnt = 0;
int tot = 0;
DSU() {
}
DSU(int n) {
init(n);
}
void init(int n) {
f.resize(n);
cnt0.resize(n);
cnt1.resize(n);
tag.resize(n);
val.resize(n);
std::iota(f.begin(), f.end(), 0);
siz.assign(n, 1);
}
int find(int x) {
while (x != f[x]) {
x = f[x] = f[f[x]];
}
return x;
}
bool same(int x, int y) {
return find(x) == find(y);
}
bool merge(int x, int y) {
x = find(x);
y = find(y);
if (x == y) {
return false;
}
if(siz[x] & 1){
swap(cnt0[y] , cnt1[y]);
}
siz[x] += siz[y];
cnt0[x] |= cnt0[y];
cnt1[x] |= cnt1[y];
cnt -= tag[y];
cnt -= tag[x];
if(cnt0[x] || cnt1[x]){
if(siz[x] & 1){
tag[x] = cnt1[x];
}
else{
tag[x] = 1;
}
}
cnt += tag[x];
tot -= val[x];
tot -= val[y];
val[x] = (siz[x] + 1) / 2;
tot += val[x];
f[y] = x;
return true;
}
int size(int x) {
return siz[find(x)];
}
};
void solve()
{
int n;
cin >> n;
int a[n + 1];
set<int>st;
for(int i = 1 ; i <= n ; i ++){
cin >> a[i];
st.insert(a[i]);
}
map<int,int>mp;
map<int,int>pm;
int id = 0;
for(auto it : st){
mp[it] = ++id;
pm[id] = it;
}
vector<int>e[id + 1];
DSU dsu(n + 1);
int b[n + 1];
for(int i = 1 ; i <= n ; i ++){
b[i] = mp[a[i]];
}
for(int i = 1 ; i <= n ; i ++){
if(b[i] == id){
dsu.val[i] = 1;
dsu.cnt1[i] = 1;
dsu.tag[i] = 1;
dsu.tot++;
dsu.cnt++;
}
e[b[i]].pb(i);
}
int ans = 0;
for(int l = id; l >= 1 ; l --){
for(auto it : e[l]){
if(l != id){
dsu.val[it] = 1;
dsu.tot++;
}
}
for(auto it : e[l]){
if(it > 1){
if(b[it - 1] >= l){
dsu.merge(it - 1 , it);
}
}
if(it + 1 <= n){
if(b[it + 1] >= l){
dsu.merge(it , it + 1);
}
}
}
ans = max(ans , dsu.tot + pm[id] - (dsu.cnt == 0));
}
cout << ans << endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(0);
cout.tie(0);
cout.precision(10);
int t=1;
cin>>t;
while(t--)
{
solve();
}
return 0;
}
B
思路
由于数轴上任意两点都能构成区间,因此对于某个数而言,其被包含的区间数量为左侧点的个数*右侧点的个数,特别的,端点处需要额外加上左
侧端点个数(代表了左侧端点连到该端点上的区间)。
代码
#include <bits/stdc++.h>
using namespace std;
#define LL long long