CodeForces 1187Dサブアレイソート

問題

あなたの配列与えられた\(A_1の\) \(A_2の\)、...、\(A_N \)と配列\(B_1 \) \(B_2 \)、...、\(B_N \)

一回の操作のためには、非減少順に任意のサブアレイ並べ替えることができます\([L ... R] \)の配列の\(\)を

たとえば、\(= [4,2,2,1,3,1] \)と、選択したsubbarrayの\([2 ... 5] \) そして配列が変身\([4,1、 2,2,3,1] \)

あなたは、配列にこの操作を任意の回数(おそらくゼロ)を適用することによって、配列bを得ることが可能であるかどうかを決定するように要求され\(\)

入力

最初の行は1つの整数含ま\を(T(1≤t≤3⋅10^ 5)\) -クエリの数。

各クエリの最初の行は1つの整数含ま\(N(1≤n≤3⋅105)を\)

各クエリの2行目には含まれてい\(N \)整数\(A_1、A_2、...、A_N(1≤a_i≤nを)\)

各クエリの3行目は、n個の整数を含む(B_1、B_2、...、B_N(1≤b_i≤n)\)\

それが保証される(\ \和{N}≤3⋅10^ 5 \)試験におけるすべてのクエリを超えます。

出力

(任意の文字の場合)各クエリ印刷YESのため、そうでなければ(任意の文字の場合)配列bとNOを得ることが可能である場合。

入力

4
7
1 7 1 4 4 5 6
1 4 4 5 6 7
5
1 1 3 3 5
1 1 3 3 5
2
1 1
1 2
3
1 2 3
3 2 1

出力

YES
YES
NO
NO

注意

最初のテストケースにサブアレイ並べ替えることができ\を(A_1 ... A_5 \)その後になります、\([1,1,4,4,7,5,6] \) 次いでソートサブアレイ\(A_5 ... a_6 \)

感想

この問題は、あまりにも多くの、なされなければならないです仲間ブログ。
タイムリーブレイク- OIは、ここでは「悪い」習慣をもたらしました。複数のデータセットは、それが答えのセットを決定し、どこでもACMは、タイムリーな休憩の後、グループは、データの読み取りが次のセット、自然WAを読まされて完了していません。
このタイトル曲理由の朝-経験不足なので、私はコードを破る時に問題が表示されません。

また、これは、使用するマークダウン、値下げ素敵で書かれた私の最初のブログです。

問題解決のためのアイデア

サポートされるオペレーティングサブ範囲は、我々はあなたが左端に間隔の範囲内で移動の最小値を置くことができ、右端に間隔の最大範囲内で移動できることを意味し、昇順にソートされます。

B、デジタルだけでなく、適切な左の各々について、左から右に、Bが入力され、私たちは第二を使用するので、左端の最小間隔に移動。実際には、常に左端に移動するとは思わない、範囲内の最小値は、左上の任意の場所に移動することができ、他には、(左の最小値と最小値の各ソートの最初の数を注文番号には影響しません2つの数の合計)。

第一の配列を読み取り、前処理後の背後にあるパイルは、その後、順次、B読み出し(以下、[B]迅速POSを見つけるために、前記)と言います。
(i番目とする)各読み取りBについて、最初に出現(POS [B])におけるデジタルBの位置を検索します。

  • あなたは無限の場所を見つけた場合は、他の言葉での年の数がこれを持っていない、そして、答えはNOです、私たちは別れることができますフラグが偽のフラグを設定し、残りのデータ、出力NOを読み取ることができます。
  • あなたが場所を見つけた場合は、私たちの目標は、このB I、利用できる前に思考を配置するために前進すること、bは[B]私は、POSする配列の添字の間であることが最低限必要です。
  • さらに、i番目のBを読み込み、前述の説明I-1の位置は完了、または前面または背面一致した、I-1は、米国に影響を与えないこと、bより特定の、INFの数に設定されています。
  • ケースの内部が想定されるように[B]この範囲で、████▂██bは、█画像が左に、彼らは私達を妨害しないB、bに以上の数を表すPOS 1を考えます。▂bより少ない画像数を表し、もちろん、使用されない(それはINFを使用するように構成された)、それはBブロックの左、換言すれば、Bは右▂期間に左に移動することができる(または)動きません。
    • ▂今私が残った場合は、私やPOSの最小値は、[B]の答えはNOであると、B未満です。
    • 私は右に▂、またはIは、POSする場合今[B]は、この移動が完了することができ、Bの最小値です。しかし、今回の完了後、我々は見つけるでしょう、▂または左に、使用されていません。aとbが同じ長さなので(霧)、▂が使用される場所を後でので、我々は、除外している前に、A、Bは、例異なる番号が含ま▂必要性を右に(右にシフトすることが▂左)が、少なくとも1つのブロックされたああBの権利は▂、Bは、正しい宛先を移動することができなかった▂、▂より大きい。
  • 要約すると、POSに1 [B]インターバルの最小値がB未満である場合、答えとにかくNO。
  • 同様に、我々は(スリープ状態にしようと、遅すぎる、実際には)それを証明することができ、POSへ1の最小値は、[B]は常にBに等しい範囲内ならば、目標に到達することができ、答えはYESです

次に、でも更新間隔最小に、いくつかの小さな場所を改善ツリーライン、非常に便利に使用しています。クイック検索のPOS [B]、アイデアはPOSアレイとNXT Moのチームがしばしば現れる配列に似ています。加えて、各アレイ内のmemsetは、すべての18個のテストポイント明確ではない(コードの59行を参照)は非常に異常です。
SDOI2009 HHネックレス

ソース

#include <stdio.h>
#include <string.h>
#include <algorithm>
int T;
int n;
int a[300010], nxt[300010], pos[300010];
struct Segtree
{
    int l, r;
    int min;
} s[1200010];
inline int lson(int x) { return x << 1; }
inline int rson(int x) { return x << 1 | 1; }
inline void pushup(int x) { s[x].min = std::min(s[lson(x)].min, s[rson(x)].min); }
void build(int x, int l, int r)
{
    s[x] = {l, r, 0};
    if (l == r)
    {
        s[x].min = a[l];
        return;
    }
    int mid = l + r >> 1;
    build(lson(x), l, mid);
    build(rson(x), mid + 1, r);
    pushup(x);
}
void update(int x, int position)
{
    if (position > s[x].r || position < s[x].l)
        return;
    if (s[x].l == s[x].r && s[x].l == position)
    {
        s[x].min = 0x7fffffff;
        return;
    }
    update(lson(x), position);
    update(rson(x), position);
    pushup(x);
}
int que(int x, int l, int r)
{
    if (r < s[x].l || l > s[x].r)
        return 0x7fffffff;
    if (l <= s[x].l && s[x].r <= r)
        return s[x].min;
    return std::min(que(lson(x), l, r), que(rson(x), l, r));
}

int main()
{
    //freopen("test.in","r",stdin);
    scanf("%d", &T);
    while (T--)
    {
        scanf("%d", &n);
        for (int i = 1; i <= n; i++)
            scanf("%d", a + i);
        memset(nxt, 0x7f, sizeof(int)*(n+2));//第18个测试点十分丧病,T是几十万,每组n是1
        memset(pos, 0x7f, sizeof(int)*(n+2));
        for (int i = n; i >= 1; i--)
        {
            nxt[i] = pos[a[i]];
            pos[a[i]] = i;
        }
        build(1, 1, n);
        bool ok = 1;
        for (int i = 1, b; i <= n; i++)
        {
            scanf("%d", &b);
            if(!ok) continue;//不要break,数据要读完
            if (pos[b] == 0x7f7f7f7f)
                ok = 0;
            if (que(1, 1, pos[b]) == b)
            {
                update(1, pos[b]);
                pos[b] = nxt[b];
            }
            else
                ok = 0;
        }
        puts(ok ? "YES" : "NO");
    }
    return 0;
}

おすすめ

転載: www.cnblogs.com/wawcac-blog/p/11229396.html