Codeforces Round 873 (Div. 2) D1
题意:给出一个数组,对于其子区间的美,其定义是最少的花费使得子区间内升序
每一次操作可以选择l,r,使得[l,r]内按升序排序,花费为r-l
求所有子区间的美的和
Solution
很厉害的操作
因为D1的n不大,可以从前往后枚举所有区间
对于a[i]来说,如果前面存在a[j]>a[i],那么至少要有操作区间是包含[j,i]的,那么我们可以把[l,r]看成若干段区间组成的,并且每一段区间的最大值是单调递增,即[l1,r1],[l2,r2]...[ln,rn],当枚举到下一个区间时,找到最后一个最大值比a[i]小的区间,这里可以用单调栈来维护,同时可以维护一下每一段的区间长度,如果区间最大值比a[i]大,那么a[i]与区间合并,并且与下一个区间比较,直到栈空或者最大值比a[i]小
void solve()
{
int n;cin>>n;
for(int i=1;i<=n;i++)cin>>a[i];
int ans=0;
for(int i=1;i<=n;i++)
{
vector<int>v1,v2;
v1.push_back(a[i]);
v2.push_back(0);
int res=0;
for(int j=i+1;j<=n;j++)
{
int len=0;
int o=v1.back();
while(v1.size()&&v1.back()>a[j])
{
res-=v2.back();
len+=v2.back()+1;
v1.pop_back(),v2.pop_back();
}
if(len==0)
{
o=a[j];
}
res+=len;
v1.push_back(o);
v2.push_back(len);
ans+=res;
}
}
cout<<ans<<"\n";
}

浙公网安备 33010602011771号