問題DTOJの#1438ドワーフキュー(ラインナップ)へのソリューション

ようこそ私Luoguスペース


[タイトル]効果

そこ\(N- \)の高さ\([1、\ n]は \) と、キュー内の異なる人々 。

2つの動作モードがあります。

  1. 位置してみましょう\(X、\ yを用\)の場所を入れ替えます。
  2. 範囲指定された\([L、\ R&LT]を\)連続した配列か並ぶ高さ範囲内の誰に尋ねます。

二つの出力操作要求。


[説明]

セグメントツリー

非常に簡単な操作。

操作IIの場合:

発明者らは、高\([L、\ R] \) のヒトコンセンサスの\(K =(R-L + 1)\) A。

私達はちょうどこの範囲の高さを見つける必要がある、との座標の人々の左端と右端に立っていました。

\((\)右座標- \(\)左座標\(+ 1)\)に等しい場合、値(k個の\)\、その\(k個の\)個人が単に連続配列を並びます。

それがより大きい場合、\(k個\)個人が他の人の数の間に挿入され、表示されたよりも小さくはあり得ません。

だから我々は、最大と最小の座標問い合わせをサポートする必要があります。

次のセグメントツリーのために背の高いターゲットを構築するために、座標、クエリ間隔の最大値と最小値の座標に対応する高さ値。


[コード]

// output format !!
// long long !!
#include <bits/stdc++.h>
#define H puts("HYX")
#define ls (x<<1)
#define rs (x<<1|1)
const int MAXN = 200000+10;
using std::max; using std::min; using std::swap;
struct TREE{int Max, Min;}t[MAXN*4];

int n, m, h[MAXN], loc[MAXN], L, R;

void build(int x, int l, int r){
    if(l == r) return t[x].Max = t[x].Min = loc[l], void();
    int mid = (l+r)>>1;
    build(ls, l, mid), build(rs, mid+1, r);
    t[x].Max = max(t[ls].Max, t[rs].Max);
    t[x].Min = min(t[ls].Min, t[rs].Min);
}
void query(int x, int l, int r, int ql, int qr){
    if(ql<=l && r<=qr){
        L = min(L, t[x].Min);
        R = max(R, t[x].Max);
        return;
    }
    int mid = (l+r)>>1;
    if(ql <= mid) query(ls, l, mid, ql, qr);
    if(qr > mid) query(rs, mid+1, r, ql, qr);
}
void modify(int x, int l, int r, int p, int v){
    if(l == r) return t[x].Max = t[x].Min = v, void();
    int mid = (l+r)>>1;
    if(p <= mid) modify(ls, l, mid, p, v);
    else modify(rs, mid+1, r, p, v);
    t[x].Max = max(t[ls].Max, t[rs].Max);
    t[x].Min = min(t[ls].Min, t[rs].Min);
}
int main(){
    scanf("%d%d", &n, &m);
    for(int i=1; i<=n; ++i) scanf("%d", h+i), loc[h[i]] = i;
    build(1, 1, n);
    while(m--){
        int op, x, y;
        scanf("%d%d%d", &op, &x, &y);
        if(op == 1){
            modify(1, 1, n, h[y], x);
            modify(1, 1, n, h[x], y);
            swap(h[x], h[y]), swap(loc[h[x]], loc[h[y]]);
        }
        else{
            L = 1e9, R = 0;
            query(1, 1, n, x, y);
            if(R-L+1 == y-x+1) puts("YES");
            else puts("NO");
        }
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/bosswnx/p/10988258.html