Codeforces Round #569 (Div. 2) C. Valeriy and Deque(双端队列+循环节)

标签(空格分隔): 题解(codeforces)


ps:没看别人写的。刚刚自己写1A.昨晚刚看了这个题目感觉就会做啊
但是想到B题也会做。最后还有50min的时候想用20分钟写这个.然后
写了写想到B题自己也会。不如继续B题,马上解决了再来搞C.没想到
最后栽在了B题。导致最后B,C都没有搞出来。血亏掉分.

这是一个双端队列的操作
容易看出题目描述的操作在第一个最大值达到队首的时候的状态假设此时的时刻是t.容易知道t <= n.我们保存1..t-1次的答案在v中,假设t时刻队列的情况是a1 a2 a3 a4 ... an.容易知道接下来的操作总是最大的那个在对首.然后后面的一直循环往复.假设此时a1 >= max{ai, (2 <= i <= n)}:
a1 a2 a3 a4 .. an
如果a1 = a2.按照题目要求.我们需要把a2放在队首.把a1放在队尾.但是由于a1=a2.将a1放在对首.将a2放在队尾等价。所以题目所描述的操作.等价于.a1 >= ai将a1放在队首.ai放在对尾部.所以会出现下面的局面.
时刻 序列
t a1 a2 a3 a4 .. an
t+1 a1 a3 a4 .. an a2
t+2 a1 a4 .. an a2 a3
t+3 a1 .. an a2 a3 a4
t+n-2 a1 an a2 a3... an-1

t+n-1 a1 a2 a3 a4 .. an
.....

所以接下来就是以n-1作为循环长度的序列.

那么对于询问m.如果m <= t-1.那么答案就在v中取即可.
m > t-1. m -= (t-1).
a2 a3 a4 .. an
1 2 3 .. n-1
m % (n-1).
如果m=0.输出a1 和 an
否则.输出a1 和 m+1

#pragma GCC optimize("O2") 
#include 
using namespace std;

#define dbg(x) cerr << #x"=" << x << endl;
typedef long long LL;
const int MAX_N = 1e5+100;
int que[4*MAX_N];
int n,q;
LL m;
int a[MAX_N];

int main(){
    //freopen("in.txt","r",stdin);    
    ios::sync_with_stdio(0); cin.tie(0);
    cin >> n >> q;
    int s = 0, t = 0;
    int mx = 0;
    for(int i = 1; i <= n; ++i){
        cin >> a[i];
        mx = max(mx, a[i]);
        que[t++] = a[i];
    } 
    vector > v;
    int tim = 1; // 一开始是1时刻 
    while(que[s] != mx){
        int A = que[s++];
        int B = que[s++];
        v.push_back(make_pair(A, B));
        if(A > B){
            que[--s] = A;
            que[t++] = B;
        } else {
            que[--s] = B;
            que[t++] = A;
        }
        ++tim;
    }
    int idx = 0;
    for(int i = s; i < t; ++i){
        a[++idx] = que[i];
    }
    while(q--){
        cin >> m;
        if(m <= tim-1){
            if(m-1 < v.size()) {
                cout << v[m-1].first << " " << v[m-1].second << endl;
            }
        } else {
            m -= (tim-1);
            m %= (n-1);
            if(m == 0) cout << a[1] << " " << a[n] << endl;
            else cout << a[1] << " " << a[m+1] << endl;
        }
    }
    return 0;
}

你可能感兴趣的:(Codeforces Round #569 (Div. 2) C. Valeriy and Deque(双端队列+循环节))