牛客寒假训练赛2-F-splay/双端队列

前言:

这题可以 s p l a y splay splay暴力模拟,可以双端队列模拟。

题目大意:

给一个序列。选择一个长度k,从左到右有顺序的进行 r e v e r s e reverse reverse或者不。问你是否能够将其变成有序.

题目思路:

方法一:双端队列

暴力模拟 O ( n 2 ) O(n^2) O(n2)。观察到这个过程是每次凑齐一个长度为 k k k的区间,然后考虑是否作整体反转.

谈到整体反转就可以使用双端队列。因为双端队列两边都可以出入队。所以正着读,反着读就相当于反转了。

做法1:自己实现六个函数(push_back,push_front,getback,getfront,pop_back,pop_front).根据反转标记来决定正反。比如说:push_back().如果有反转标记,就实际调用push_front,否则直接调用push_back.

做法2:额外维护一个镜像队列。同时操作且保证两者的操作是镜像的.然后将其中一个当作是当前队列。然后每次reverse的时候就转到另一个队列。

这里只放做法2.实现更简单

#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define vi vector<int>
#define vll vector<ll>
#define fi first
#define se second
const int maxn = 1e6 + 5;
const int mod = 1e9 + 7;
int a[maxn];
int tag = 1;
deque<int> q[2];
int b[maxn];
int main()
{
    
    
    ios::sync_with_stdio(false);
    int n; cin >> n;
    for (int i = 1 ; i <= n ; i++) cin >> a[i] , b[a[i]] = i;
    int id = 0 , k;
    for (int i = 1 ; i <= n ; i++){
    
    
        if (a[i] != i) {
    
    
            id = i;
            break;
        }
    }
    k = b[id] - id + 1;
    if (k == 1){
    
    
        cout << "yes" << endl;
        cout << k << endl;
        return 0;
    }
    bool ok = true;
    int now = id;
    for (int i = id ;  ; ){
    
    
        while (i <= n && (int)q[tag].size() < k) {
    
    
            q[tag].push_back(a[i]);
            q[!tag].push_front(a[i]);
            i++;
        }
        if ((int)q[tag].size() != k){
    
    
            while (q[tag].size() && q[tag].front() == now) {
    
    
                now++;
                q[tag].pop_front();
                q[!tag].pop_back();
            }
            if (q[tag].size()) ok = false;
            break;
        }
        if (q[tag].back() == now){
    
    
            q[tag].pop_back();
            q[!tag].pop_front();
            now++;
            tag = !tag;
        }
        else if (q[tag].front() == now) {
    
    
            q[tag].pop_front();
            q[!tag].pop_back();
            now++;
        }
        else {
    
    
            ok = false;
            break;
        }
    }
    if (ok){
    
    
        cout << "yes" << endl;
        cout << k << endl;
        return 0;
    }
    cout << "no" << endl;
    return 0;
}

猜你喜欢

转载自blog.csdn.net/qq_35577488/article/details/114917696