数据结构:栈(区间问题)

码蹄集OJ-小码哥的栈

复制代码
#include<bits/stdc++.h> 
using namespace std;
#define int long long
const int N=1e6+7;
struct MOOE
{
    int ll,rr;
};
stack<MOOE>st;
signed main( )
{
    ios::sync_with_stdio(false);
    cin.tie(nullptr);
    int n;
    cin>>n;
    while(n--)
    {
        int opt;
        cin>>opt;
        if(opt==1)
        {
            int l,r;
            cin>>l>>r;
            st.push({l,r});
        }
        if(opt==2)
        {
            int k;
            cin>>k;
            int result=0;
            while(k)
            {
                int l=st.top().ll;
                int r=st.top().rr;
                int size=r-l+1;
                if(k<size)
                {
                    result+=(2*r-k+1)*k/2;
                    st.pop();
                    st.push({l,r-k});
                    k=0;
                }
                else
                {
                    result+=(l+r)*size/2;
                    k-=size;
                    st.pop();
                }
            }        
            cout<<result<<endl;
        }

    }
    return 0;
}

定义一个结构体MOOD变量,含有ll与rr两个成员。定义一个st栈保存节点(栈内节点可以是一个数也可以是一个范围),每次 push({l, r}) 就是把一个 MOOE 对象压栈,也就是栈内的每个节点都有两个成员。

当输入的opt为1时,将范围作为节点压入栈中。

当输入的opt为2时,要考虑k的两种情况:一种可能小于栈顶范围,一种大于栈顶范围。如果小于栈顶范围,通过等差数列求和公式得出结果;当大于栈顶范围时,只要将栈顶范围的和求出后,再pop出后,反复多次还会回到第一种情况中。在两种条件外套上大循环,当是第一种情况,循环停止,第二种情况时,将k减去pop出的节点的大小,再进入循环。