結果

問題 No.284 門松と魔法(2)
ユーザー yosupotyosupot
提出日時 2015-09-19 11:41:51
言語 C++11
(gcc 11.4.0)
結果
WA  
実行時間 -
コード長 2,633 bytes
コンパイル時間 949 ms
コンパイル使用メモリ 113,596 KB
実行使用メモリ 12,580 KB
最終ジャッジ日時 2023-09-26 13:33:45
合計ジャッジ時間 3,413 ms
ジャッジサーバーID
(参考情報)
judge15 / judge11
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 3 ms
7,516 KB
testcase_01 AC 3 ms
7,428 KB
testcase_02 AC 3 ms
7,468 KB
testcase_03 AC 3 ms
7,492 KB
testcase_04 WA -
testcase_05 WA -
testcase_06 WA -
testcase_07 WA -
testcase_08 WA -
testcase_09 AC 3 ms
7,520 KB
testcase_10 AC 4 ms
7,584 KB
testcase_11 AC 4 ms
7,440 KB
testcase_12 AC 3 ms
7,764 KB
testcase_13 AC 3 ms
7,656 KB
testcase_14 WA -
testcase_15 AC 3 ms
7,656 KB
testcase_16 AC 4 ms
7,520 KB
testcase_17 WA -
testcase_18 WA -
testcase_19 AC 4 ms
7,444 KB
testcase_20 AC 3 ms
7,496 KB
testcase_21 AC 3 ms
7,540 KB
testcase_22 AC 4 ms
7,500 KB
testcase_23 WA -
testcase_24 WA -
testcase_25 WA -
testcase_26 AC 4 ms
7,448 KB
testcase_27 AC 3 ms
7,548 KB
testcase_28 AC 3 ms
7,448 KB
testcase_29 AC 138 ms
9,948 KB
testcase_30 WA -
testcase_31 WA -
testcase_32 AC 169 ms
12,556 KB
testcase_33 AC 119 ms
12,508 KB
testcase_34 AC 121 ms
12,580 KB
testcase_35 AC 4 ms
7,752 KB
testcase_36 AC 3 ms
7,768 KB
testcase_37 AC 66 ms
7,844 KB
testcase_38 WA -
testcase_39 WA -
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <iostream>
#include <cstdio>
#include <cassert>
#include <cstring>
#include <vector>
#include <valarray>
#include <array>
#include <queue>
#include <set>
#include <unordered_set>
#include <map>
#include <unordered_map>
#include <algorithm>
#include <cmath>
#include <complex>
#include <random>

using namespace std;
typedef long long ll;
typedef pair<int, int> P;

/**
 * RangeMinQuery
 *
 * 区間系データ構造の中ではFenwick Treeの次あたりに有名?
 * 値の変更と区間の最小値がO(logn)で処理できる
 *
 * template引数のint Sは要素数が2^Sであることを示す
 */
template <int S>
struct RangeMinQuery {
    static const int N = 1<<S;
    typedef ll D;
    static const D INF = 1LL<<62;
    D seg[2*N];

    void init() {
        fill_n(seg, 2*N, 0);
    }

    void init(int n, D x[]) {
        init();
        for (int i = 0; i < n; i++) {
            seg[i+N] = x[i];
        }
        for (int i = N-1; i >= 1; i--) {
            seg[i] = max(seg[i*2], seg[i*2+1]);
        }
    }

    /// i番目の要素をxにする
    void set(int i, D x) {
        i += N;
        seg[i] = x;
        while (i) {
            i /= 2;
            seg[i] = max(seg[i*2], seg[i*2+1]);
        }
    }

    /// [a, b)での最小値を求める
    D get(int a, int b, int k = 1, int l = 0, int r = N) {
        if (r <= a || b <= l) return -INF;
        if (a <= l && r <= b) return seg[k];
        int md = (l+r)/2;
        D dl = get(a, b, k*2, l, md);
        D dr = get(a, b, k*2+1, md, r);
        return max(dl, dr);
    }
};


const int MN = 100100;
int n;
int a[MN];

RangeMinQuery<17> rm1, rm2;

int solve() {
	rm1.init(); rm2.init();
	rm1.set(a[0], 1);
	rm2.set(a[0], 1);
	// printf("te %d %lld \n", a[0], rm1.get(1, 2));
	// for (int i = 0; i < n; i++) {
	// 	printf("%d ", a[i]);
	// } printf("\n");
	for (int i = 1; i < n; i++) {
		rm1.set(a[i], max(rm1.get(a[i], a[i]+1), 1+rm2.get(0, a[i])));
		rm2.set(a[i], max(rm2.get(a[i], a[i]+1), 1+rm1.get(a[i]+1, MN)));
		// printf("rm1 ");
		// for (int j = 0; j <= n; j++) {
		// 	printf("%lld ", rm1.get(j, j+1));
		// } printf("\n");
		// printf("rm2 ");
		// for (int j = 0; j <= n; j++) {
		// 	printf("%lld ", rm2.get(j, j+1));
		// } printf("\n");
	}

	int re = max(rm1.get(0, MN), rm2.get(0, MN));

	if (re <= 2) re = 0;

	return re;
}


int main() {
	cin >> n;
	set<int> s;
	for (int i = 0; i < n; i++) {
		cin >> a[i];
		s.insert(a[i]);
	}
	vector<int> v(s.begin(), s.end());
	for (int i = 0; i < n; i++) {
		a[i] = lower_bound(v.begin(), v.end(), a[i]) - v.begin();
		a[i]++;
	}
	cout << solve() << endl;

    return 0;
}
0