Insert 1, Insert 2, Insert 3, ...
Insert 1, Insert 2, Insert 3, ...
时间限制(普通/Java):2000MS/4000MS 内存限制:1048576KByte
描述
输入
输出
样例输入
6
1 1 2 2 3 3
样例输出
8
思路
单调栈从左到右遍历数组,遇到 1 则入栈;
若不为 1 则判断能否与最近的 1 匹配,如果能则继续,如果不能,则将栈顶的 1 出栈,并判断下一个 1
单调栈在这里应用是,遍历到一个数,然后查找与之匹配的1的位置,如果匹配的1的位置比当前栈顶元素的小,则表明栈顶的 1 与后面无法匹配,则出栈;
AC代码
#include <bits/stdc++.h>
using namespace std;
#pragma GCC optimize(3)
void solve()
{
int n;
cin>>n;
int num;
vector<vector<int> >p(n+1,vector<int>());
vector<int>st;
long long ans=0;
for(int i=1;i<=n;i++)
{
cin>>num;
if(!(num-1))
{
p[num].push_back(i);
st.push_back(i);
}
else
{
int pos=0;
if(!p[num-1].empty())
{
pos=p[num-1].back();
p[num-1].pop_back();
p[num].push_back(pos);
}
while(!st.empty()&&st.back()>pos)st.pop_back();
}
ans+=st.size();
}
cout<<ans<<endl;
}
signed main()
{
ios::sync_with_stdio(false);
cin.tie(nullptr);
cout.tie(nullptr);
int _=1;
// cin>>_;
while(_--)
{
solve();
}
return 0;
}