답안 #542744

# 제출 시각 아이디 문제 언어 결과 실행 시간 메모리
542744 2022-03-27T20:32:02 Z Sorting Zoltan (COCI16_zoltan) C++17
140 / 140
217 ms 13108 KB
#include <bits/stdc++.h>

using namespace std;

typedef long long ll;
template<class T> void check_min(T &a, const T &b){ a = (a < b) ? a : b; }
template<class T> void check_max(T &a, const T &b){ a = (a > b) ? a : b; }
#define all(x) (x).begin(), (x).end()

const int N = 2e5 + 3;
const int MOD = 1e9 + 7;

int n;
pair<int, int> a[N];

pair<int, int> dp[2][N];

struct SegmentTree{
    struct Node{
        int mx, cnt;

        Node(): mx(0), cnt(0){}
        Node(int mx, int cnt): mx(mx), cnt(cnt){}

        friend Node merge(const Node &l, const Node &r){
            Node res;
            res.mx = max(l.mx, r.mx);
            res.cnt = 0;
            res.cnt += (l.mx == res.mx) ? l.cnt : 0;
            res.cnt += (r.mx == res.mx) ? r.cnt : 0;
            if(res.cnt >= MOD) res.cnt -= MOD;
            return res;
        }
    } nd[4 * N];

    void init(int n){
        fill(nd, nd + 4 * n, Node());
    }

    void update(int idx, pair<int, int> val, int i = 0, int l = 1, int r = n){
        if(idx < l || r < idx) return;
        if(l == r){
            nd[i] = Node(val.first, val.second);
            return;
        }
        int mid = (l + r) >> 1;
        update(idx, val, 2 * i + 1, l, mid);
        update(idx, val, 2 * i + 2, mid + 1, r);
        nd[i] = merge(nd[2 * i + 1], nd[2 * i + 2]);
    }

    Node query(int sl, int sr, int i = 0, int l = 1, int r = n){
        if(sr < l || r < sl) return Node();
        if(sl <= l && r <= sr) return nd[i];
        int mid = (l + r) >> 1;
        return merge(query(sl, sr, 2 * i + 1, l, mid), query(sl, sr, 2 * i + 2, mid + 1, r));
    }
} seg_tr;

int main(){
    ios::sync_with_stdio(false);
    cin.tie(NULL);

    cin >> n;
    for(int i = 1; i <= n; ++i){
        cin >> a[i].first;
        a[i].second = i;
    }
    sort(a + 1, a + n + 1);

    seg_tr.init(n);
    vector<int> to_update;
    for(int i = 1; i <= n; ++i){
        auto [mx, cnt] = seg_tr.query(a[i].second + 1, n);
        if(mx == 0) cnt = 1;
        dp[0][i] = pair{mx + 1, cnt};

        to_update.push_back(i);

        if(a[i].first != a[i + 1].first){
            for(int idx: to_update)
                seg_tr.update(a[idx].second, dp[0][idx]);
            to_update.clear();
        }
    }

    seg_tr.init(n);
    to_update.clear();
    for(int i = n; i >= 1; --i){
        auto [mx, cnt] = seg_tr.query(a[i].second + 1, n);
        if(mx == 0) cnt = 1;
        dp[1][i] = {mx + 1, cnt};

        to_update.push_back(i);

        if(a[i].first != a[i - 1].first){
            for(int idx: to_update)
                seg_tr.update(a[idx].second, dp[1][idx]);
            to_update.clear();
        }
    }

    dp[0][0].second = 1;
    dp[1][n + 1].second = 1;

    pair<int, ll> ans{0, 0};
    for(int i = 1; i <= n; ++i){
        pair<int, ll> cand{dp[0][i].first + dp[1][i].first - 1, (ll)dp[0][i].second * (ll)dp[1][i].second % MOD};
        if(cand.first == ans.first){
            ans.second += cand.second;
            if(ans.second >= MOD)
                ans.second -= MOD;
        }
        if(cand.first > ans.first)
            ans = cand;
    }
    int cnt = n - ans.first;
    while(cnt--){
        ans.second <<= 1;
        if(ans.second >= MOD) ans.second -= MOD;
    }

    cout << ans.first << " " << ans.second << "\n";
}
# 결과 실행 시간 메모리 Grader output
1 Correct 3 ms 6484 KB Output is correct
2 Correct 4 ms 6592 KB Output is correct
3 Correct 4 ms 6484 KB Output is correct
4 Correct 3 ms 6484 KB Output is correct
5 Correct 4 ms 6484 KB Output is correct
6 Correct 3 ms 6484 KB Output is correct
7 Correct 4 ms 6612 KB Output is correct
8 Correct 4 ms 6600 KB Output is correct
9 Correct 4 ms 6612 KB Output is correct
10 Correct 4 ms 6596 KB Output is correct
11 Correct 122 ms 11600 KB Output is correct
12 Correct 111 ms 10824 KB Output is correct
13 Correct 103 ms 10504 KB Output is correct
14 Correct 135 ms 11084 KB Output is correct
15 Correct 173 ms 12252 KB Output is correct
16 Correct 217 ms 13108 KB Output is correct
17 Correct 180 ms 12492 KB Output is correct
18 Correct 163 ms 12492 KB Output is correct
19 Correct 168 ms 12532 KB Output is correct
20 Correct 162 ms 12452 KB Output is correct