前情
题意:
问题陈述
有一个(蛇)队列。最初,队列是空的。
你会得到 \(Q\) 个查询,这些查询应按给出的顺序处理。查询有三种类型:
- 类型 \(1\) :以
1 l
的形式给出。一条长度为 \(l\) 的蛇会被添加到队列的末尾。如果添加前队列为空,则新添加的蛇的头部位置为 \(0\) ;否则,它就是队列中最后一条蛇的头部坐标与最后一条蛇的长度之和。 - 类型 \(2\) :以 "2 "的形式给出。队列最前面的蛇离开队列。保证此时队列不是空的。假设 \(m\) 是离开队列的蛇的长度,那么队列中剩余的每条蛇的头部坐标都会减少 \(m\) 。
- 类型 \(3\) :以
3 k
的形式给出。输出距离队列前列 \(k\) 的蛇头坐标。保证此时队列中至少有 \(k\) 条蛇。
思路
类型 \(1\) 和类型 \(2\) 做起来都很简单,因为是头部删除尾部入队,首选 deque
来处理,时间复杂度均为 \(O(1)\) ,但如果类型 \(3\) 用循环一遍进行减去更新的话最坏时间复杂度为 \(O(N)\) ,整体时间复杂度为 \(O(N^2)\) ,在 \(1 \leq Q \leq 3 \times 10^{5}\) 的情况下,通过是不现实的。
优化
可以设置一个偏移量进行记录全体蛇的位移情况,每当删除头蛇时,偏移量就加上头蛇的长度,到查询时直接用第 \(k\) 条蛇的蛇头坐标减去偏移量即可,这样使时间复杂度优化到 \(O(N)\) 。
注意事项
需要注意的是,偏移量只有在删除蛇时才会改变,因为删除蛇会影响剩余蛇的相对头部坐标,而新添加的蛇是基于队列末尾的蛇来计算头部坐标的。还有记得开long long,被这里卡了。
代码
#include <bits/stdc++.h>
#define int long long
using namespace std;
struct Snake{
int hd,len;
};
deque <Snake> dq;
signed main(){
int Q;
cin>>Q;
int mov=0;//偏移量记录移动
while(Q--){
int q;
cin>>q;
if(q==1){//插入操作
int l;
cin>>l;
int nh=0;
if(!dq.empty()){
nh=dq.back().hd+dq.back().len;//计算头部坐标
}
dq.push_back({nh,l});
}
if(q==2){//删除
int er=dq.front().len;
dq.pop_front();
mov+=er;//增加偏移量
}
if(q==3){
int k;
cin>>k;
cout<<dq[k-1].hd-mov<<endl;//查询
}
}
return 0;
}
完美结束..
标签:int,题解,ABC389C,偏移量,Queue,队列,坐标,头部,dq From: https://www.cnblogs.com/TobyL/p/18679018