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;
}
posted @ 2023-06-26 13:22  固态H2O  阅读(7)  评论(0)    收藏  举报  来源