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;
}
posted @ 2023-08-14 18:44  Minza  阅读(34)  评论(0编辑  收藏  举报