For each i, find the largest j that aj < ai and show it by li (if there is no such j, then li = 0).
Also, find the smallest j that aj < ai and show it by ri (if there is no such j, then ri = n + 1).
This can be done in O(n) with a stack. Pseudo code of the first part (second part is also like that) :
stack s // initially empty
for i = 1 to n
while s is not empty and a[s.top()] >= a[i]
do s.pop()
if s is empty
then l[i] = 0
otherwise
l[i] = s.top()
s.push(i)
Consider that you are asked to print n integers, ans1, ans2, ..., ansn. Obviously, ans1 ≥ ans2 ≥ ... ≥ ansn.
For each i, we know that ai can be minimum element in groups of size 1, 2, ..., ri - li - 1.
Se we need a data structure for us to do this:
We have array ans1, ans2, ..., ansn and all its elements are initially equal to 0. Also, n queries. Each query gives x, val and want us to perform ans1 = max(ans1, val), ans2 = max(ans2, val), ..., ansx = max(ansx, val). We want the final array.
This can be done in O(n) with a maximum partial sum (keeping maximum instead of sum), read here for more information about partial sum.
Time complexity: 
=============================CODE==============================================
#include<bits/stdc++.h>
using namespace std;
typedef long long int lli;
stack<pair<lli,int> > s;
lli arr[1000000];
int fforward[1000000];
int bbackward[1000000];
vector<lli> ans;
vector<pair<int,lli> > span;
int main()
{
int n;
cin>>n;
for(int i=0;i<n;i++)
{
cin>>arr[i];
}
for(int i=0;i<n;i++)
{
//cout<<" going to use "<<arr[i]<<endl;
if( s.empty() || s.top().first<=arr[i] )
{
// cout<<" push"<<endl;;
s.push({arr[i],i});
}
else
{
while(!s.empty() && s.top().first>arr[i])
{
fforward[s.top().second]=(i-s.top().second);
// cout<<"pop "<<s.top().first<<" "<<" ans is "<<fforward[s.top().second]<<endl;
s.pop();
}
s.push({arr[i],i});
}
}
while(!s.empty())
{
fforward[s.top().second]=(n-s.top().second);
s.pop();
}
/*for(int i=0;i<n;i++) cout<<fforward[i]<<" ";
cout<<endl;*/
for(int i=n-1;i>=0;i--)
{
//cout<<" going to use "<<arr[i]<<endl;
if( s.empty() || s.top().first<=arr[i] )
{
// cout<<" push"<<endl;;
s.push({arr[i],i});
}
else
{
while(!s.empty() && s.top().first>arr[i])
{
bbackward[s.top().second]=(s.top().second-i);
// cout<<"pop "<<s.top().first<<" "<<" ans is "<<fforward[s.top().second]<<endl;
s.pop();
}
s.push({arr[i],i});
}
}
while(!s.empty())
{
bbackward[s.top().second]=(s.top().second+1);
s.pop();
}
for(int i=0;i<n;i++)
{
span.push_back({fforward[i]+bbackward[i]-1,arr[i]});
// cumulated[i]=fforward[i]+bbackward[i]-1;
}
// for(int i=0;i<n;i++)cout<<cumulated[i]<<" ";
//cout<<endl;
sort(span.begin(),span.end());
int start=n-1;
set<lli> sset;
for(int sp=n;sp>=1;sp--)
{
while(start>=0 && span[start].first>=sp)
{
sset.insert(span[start].second);
start--;
}
ans.push_back(*sset.rbegin());
}
for(int i=n-1;i>=0;i--) cout<<ans[i]<<" ";
}
No comments:
Post a Comment