CF1179A Valeriy and Deque
CF1179A Valeriy and Deque
思路
首先,每次操作后会将大的那个数排至队首。所以说,当队列中最大的那个数到达队首时,队首元素将不再改变,而其他的元素依次循环。因此,我们可以记录最大数不在队首之前的操作,在其到达队首之后,记录其余元素的循环节即可。注意:需要记录使最大数到达队首的步数,以便询问时判断取用哪个数组中的答案。
Code
#include<bits/stdc++.h>
#define int long long
using namespace std;
const int MAXN = 1e5 + 5;
int n, m, maxn, a, b;
deque<int> q;
struct Ans {//记录答案
int Max, Min;
} ans[MAXN],res[MAXN];
int cnt,st;//cnt记录步数
void init(){//在最大数未到达前的操作
a = q.front();q.pop_front();
b = q.front();q.pop_front();
ans[++cnt].Max = a;
ans[cnt].Min = b;
q.push_front(max(a, b));
q.push_back(min(a, b));
}
signed main() {
scanf("%lld%lld", &n, &m);
for (int i = 1; i <= n; i++) {
int x;
scanf("%lld", &x);
maxn = max(x, maxn);
q.push_back(x);
}
while (q.front() != maxn) {
init();
}
q.pop_front();//由于队首固定,所以直接弹出
for(int i=0;i<n-1;i++){
res[i].Max=maxn;//队首数一定为最大数
res[i].Min=q.front();
q.pop_front();
}
for(int i=1;i<=m;i++){
int p;
scanf("%lld",&p);
if(p<=cnt){//答案判断
printf("%lld %lld\n",ans[p].Max,ans[p].Min);
}else{
int len=p-cnt-1;//循环的次数
printf("%lld %lld\n",res[len%(n-1)].Max,res[len%(n-1)].Min);
}
}
return 0;
}

浙公网安备 33010602011771号