Codeforces Round 873 (Div. 1) B1.Range Sorting (Easy Version)(Monotonic Stack)

topic

Given an array a(1<=ai<=1e9) of length n(n<=5e3),

For each sub-array, its beautiful value is defined as the minimum number of seconds for any number of operations to make the sub-array increment

For each operation, you can select two subscripts [l, r], and sort the interval [l, r] in increasing order, and the cost is rl seconds

Find the sum of beauty values ​​of all subarrays

source of ideas

hxu10 code

answer

It feels similar to the BZOJ1345 sequence problem Sequence (thinking/monotonic stack)_Code92007's blog-CSDN blog

The monotonic stack is still very ingenious, and every time it is replenished, it feels a little amazing

Enumerate the left endpoint, traverse the right endpoint with a single increase, and maintain the maximum value of the monotonic stack, which is actually an increasing stack.

The element (mx, cost) indicates (the maximum value of the current prefix, the cost required for sorting the interval where the maximum value of the current prefix is ​​located)

Each time the current value a[j] is used to pop the maximum value greater than the current value,

This shows that if there is a number v on the left side of a[j] that is larger than a[j], at least a[j] should be changed to the left side of v,

Assuming that the original cost of changing v is cost, the current cost is cost+1,

It is equivalent to merging several intervals into one interval by popping the stack several times

After popping the stack, put the maximum value of the current prefix mx and the cost of the interval where mx is located into the stack. The first dimension guarantees the complexity

For example, 7 10 8 6 12 100, the maximum prefix is ​​7 10 10 10 12 100,

But after sweeping to 6, after popping the stack, it is actually (10,4), because 6 bounced away both 10 and 7, and merged the intervals together

Cur maintains the cost of the current interval, which is accumulated by merging several intervals

The sum maintains the sum of the element costs from the bottom of the stack to the top of the stack, which decreases every time one is played, and increases every time one is placed

the code

#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
#define rep(i,a,b) for(int i=(a);i<=(b);++i)
#define per(i,a,b) for(int i=(a);i>=(b);--i)
#define SZ(a) (int)(a.size())
#define fi first
#define se second
typedef pair<int,int> P;
const int N=5e3+10;
int t,n,a[N];
P stk[N];
int main(){
	cin>>t;
	while(t--){
		cin>>n;
		rep(i,1,n)cin>>a[i];
		ll ans=0;
		rep(i,1,n){
			int c=0,mx=a[i],sum=0;
			rep(j,i,n){
				int cur=0;
				while(c && stk[c].fi>a[j]){
					mx=max(mx,stk[c].fi);
					cur+=stk[c].se+1;
					sum-=stk[c--].se;
				}
				sum+=cur;
				mx=max(mx,a[j]);
				stk[++c]=P(mx,cur);
				ans+=sum;
			}
		}
		cout<<ans<<endl;
	}
	return 0;
}

Guess you like

Origin blog.csdn.net/Code92007/article/details/130676275