結果

問題 No.1079 まお
ユーザー tarattata1tarattata1
提出日時 2020-06-12 22:54:06
言語 C++14
(gcc 12.3.0 + boost 1.83.0)
結果
WA  
実行時間 -
コード長 4,189 bytes
コンパイル時間 1,146 ms
コンパイル使用メモリ 101,048 KB
実行使用メモリ 21,184 KB
最終ジャッジ日時 2023-09-06 11:03:51
合計ジャッジ時間 4,837 ms
ジャッジサーバーID
(参考情報)
judge15 / judge11
このコードへのチャレンジ
(要ログイン)

テストケース

テストケース表示
入力 結果 実行時間
実行使用メモリ
testcase_00 AC 2 ms
4,376 KB
testcase_01 AC 1 ms
4,376 KB
testcase_02 AC 2 ms
4,380 KB
testcase_03 AC 1 ms
4,380 KB
testcase_04 WA -
testcase_05 WA -
testcase_06 WA -
testcase_07 WA -
testcase_08 WA -
testcase_09 WA -
testcase_10 WA -
testcase_11 WA -
testcase_12 WA -
testcase_13 WA -
testcase_14 WA -
testcase_15 WA -
testcase_16 AC 121 ms
18,816 KB
testcase_17 WA -
testcase_18 WA -
testcase_19 WA -
testcase_20 WA -
testcase_21 WA -
testcase_22 AC 148 ms
21,180 KB
testcase_23 AC 149 ms
21,124 KB
testcase_24 AC 153 ms
21,132 KB
testcase_25 AC 157 ms
21,120 KB
testcase_26 AC 162 ms
21,124 KB
testcase_27 AC 32 ms
7,632 KB
testcase_28 WA -
testcase_29 AC 109 ms
21,124 KB
testcase_30 AC 111 ms
21,184 KB
testcase_31 AC 35 ms
7,324 KB
権限があれば一括ダウンロードができます

ソースコード

diff #

#include <cstdio>
#include <string>
#include <cstring>
#include <cstdlib>
#include <cmath>
#include <algorithm>
#include <vector>
#include <set>
#include <map>
#include <queue>
#include <stack>
#include <list>
#include <iterator>
#include <cassert>
#include <numeric>
#include <functional>
#pragma warning(disable:4996) 

typedef long long ll;
typedef unsigned long long ull;
#define MIN(a, b) ((a)>(b)? (b): (a))
#define MAX(a, b) ((a)<(b)? (b): (a))
#define LINF  9223300000000000000
#define LINF2 1223300000000000000
#define LINF3 1000000000000
#define INF 2140000000
const long long MOD = 1000000007;
//const long long MOD = 998244353;

using namespace std;


const long long INF2 = (((ll)1<<31)-1);

template<class T> class SegTree   // 0-indexed
{
private:
    int n;             // 葉の数
    vector<T> data;    // ノードの値を持つ配列
    T def;                // 初期値かつ単位元
    
    T operation(T a, T b)    // 区間クエリで使う処理
    {
        return min(a, b);   // 区間minクエリ
        //return a+b;       // 区間和クエリ
    }

    T update(T a, T b)      // 点更新で使う処理
    {
        //return a+b;   // 加算の場合
        return b;       // 更新の場合
    }

    // 区間[a,b)の総和。ノードk=[l,r)に着目している。
    T _query(int a, int b, int k, int l, int r) {
        if (r <= a || b <= l) return def; // 交差しない
        if (a <= l && r <= b)
            return data[k]; // a,l,r,bの順で完全に含まれる
        else {
            T c1 = _query(a, b, 2 * k + 1, l, (l + r) / 2); // 左の子
            T c2 = _query(a, b, 2 * k + 2, (l + r) / 2, r); // 右の子
            return operation(c1, c2);
        }
    }
 
public:
    SegTree(int _n) {     // _n:必要サイズ
        def = INF2;        // 初期値かつ単位元
        //def = 0;        // 初期値かつ単位元(0:区間和の場合)
        n = 1;
        while (n < _n) n *= 2;
        data = vector<T>(2 * n - 1, def);
    }

    // 場所i(0-indexed)の値をxで更新
    void change(int i, T x) {
        i += n - 1;
        data[i] = update(data[i], x);
        while (i > 0) {
            i = (i - 1) / 2;
            data[i] = operation(data[i * 2 + 1], data[i * 2 + 2]);
        }
    }

    // [a, b)の区間クエリを実行
    T query(int a, int b) {
        return _query(a, b, 0, 0, n);
    }
 
    // 添字でアクセス
    T operator[](int i) {
        return data[i + n - 1];
    }
};

void solve()
{
    int n, K;
    scanf("%d%d", &n, &K);

    SegTree<long long> S(n);
    vector<int> a(n);
    int i;
    for (i = 0; i < n; i++) {
        scanf("%d", &a[i]);
        S.change(i, a[i]);
    }

    vector<int> left(n, -INF);
    map<int, int> z0;
    for (i = n - 1; i >= 0; i--) {
        auto it = z0.find(a[i]);
        if (it != z0.end()) {
            int r=it->second;
            ll tmp=S.query(i, r + 1);
            if (tmp == a[i]) {
                left[r] = MAX(left[r], i);
            }
        }
        z0[a[i]] = i;
    }

    ll ans = 0;
    map<int, vector<pair<int,ll> > > z;
    int lim = -INF;
    for (i = 0; i < n; i++) {
        auto it0 = z.find(a[i]);
        if (it0 != z.end()) {
            vector<pair<int,ll> >& v0=it0->second;
            ll val0=v0.back().second;
            ll val = val0 + i;
            v0.push_back(make_pair(i, val));
        }
        else {
            z[a[i]].push_back(make_pair(i, i));
        }

        lim = MAX(lim, left[i]);
        int tmp=K-a[i];

        auto it = z.find(tmp);
        if (it != z.end()) {
            vector<pair<int,ll> >& v=it->second;
            pair<int, ll> tt = make_pair(lim + 1, -LINF);
            int k=lower_bound(v.begin(), v.end(), tt) - v.begin();
            ll tmp0 = (k > 0 ? v[k - 1].second : 0);
            ans += (-v[(int)v.size() - 1].second + tmp0 + (i+1)*((int)v.size()-k));
        }
    }
    printf("%lld\n", ans);

    return;
}


int main(int argc, char* argv[])
{
#if 1
    solve();
#else
    int T;
    scanf("%d", &T);
    int t;
    for(t=0; t<T; t++) {
        //printf("Case #%d: ", t+1);
        solve();
    }
#endif
    return 0;
}
0