数据结构:栈(区间问题)
码蹄集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出的节点的大小,再进入循环。