题解:P17720 「FunMusic OI 1C」旋律 / Melody
Witness_sc · · 题解
思路
考虑枚举区间的左端点
为了维护区间内最长的连续整数段,可以使用并查集。每个数初始时单独属于一个集合,集合大小为
每次合并后,维护当前最大的集合大小,即可得到当前区间的
参考代码
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int N=3010;
int n;
int a[N],fa[N],sz[N],vis[N];
int find(int x){
if(fa[x]!=x){
fa[x]=find(fa[x]);
}
return fa[x];
}
void merge(int x,int y){
x=find(x);
y=find(y);
if(x!=y){
fa[x]=y;
sz[y]+=sz[x];
}
}
signed main(){
ios::sync_with_stdio(0);
cin.tie(0);
cout.tie(0);
cin>>n;
for(int i=1;i<=n;i++){
cin>>a[i];
}
int ans=0;
for(int l=1;l<=n;l++){
memset(vis,0,sizeof(vis));
for(int i=1;i<=n;i++){
fa[i]=i;
sz[i]=1;
}
int mx=0;
for(int r=l;r<=n;r++){
int x=a[r];
vis[x]=1;
if(x>1 && vis[x-1]){
merge(x,x-1);
}
if(x<n && vis[x+1]){
merge(x,x+1);
}
mx=max(mx,sz[find(x)]);
ans+=mx;
}
}
cout<<ans<<endl;
return 0;
}