QOJ.ac

QOJ

IDProblemSubmitterResultTimeMemoryLanguageFile sizeSubmit timeJudge time
#574123#9313. Make MaxyouthpaulTL 0ms0kbC++202.3kb2024-09-18 20:51:272024-09-18 20:51:27

Judging History

你现在查看的是最新测评结果

  • [2024-09-18 20:51:27]
  • 评测
  • 测评结果:TL
  • 用时:0ms
  • 内存:0kb
  • [2024-09-18 20:51:27]
  • 提交

answer

#include<bits/stdc++.h>
#define fore(i, l, r) for(int i = (int)(l); i < (int)(r); ++i)
#define fi first
#define se second
#define endl '\n'
#define ull unsigned long long
#define ALL(v) v.begin(), v.end()

const int INF = 0x3f3f3f3f;
const long long INFLL = 1e18;

using ll = long long;

const int N = 200005;
const int K = 18;

int LOG2[N];

int main(){
    std::ios::sync_with_stdio(false);
    std::cin.tie(nullptr);
    LOG2[0] = -1;
    fore(i, 1, N) LOG2[i] = LOG2[i >> 1] + 1;
    int t;
    std::cin >> t;
    while(t--){
        int n;
        std::cin >> n;
        const int K = LOG2[n];
        std::vector<std::vector<int>> st(n + 1, std::vector<int>(K + 1));
        std::vector<int> a(n + 1);
        std::vector<std::vector<int>> pos(n + 1);
        std::vector<int> vec;
        fore(i, 1, n + 1){
            std::cin >> a[i];
            vec.push_back(a[i]);
        }
        std::sort(ALL(vec));
        vec.erase(unique(ALL(vec)), vec.end());

        fore(i, 1, n + 1){
            a[i] = std::lower_bound(ALL(vec), a[i]) - vec.begin() + 1;
            pos[a[i]].push_back(i);
        }

        fore(i, 1, n + 1) st[i][0] = a[i];
        fore(k, 1, K + 1)
            for(int i = 1; i + (1 << k) - 1 <= n; ++i)
                st[i][k] = std::max(st[i][k - 1], st[i + (1 << k - 1)][k - 1]);

        auto query = [&](int l, int r) -> int {
            int k = LOG2[r - l + 1];
            return std::max(st[l][k], st[r - (1 << k) + 1][k]);
        };

        auto dfs = [&](auto self, int l, int r) -> ll {
            int mx = query(l, r);
            ll res = 0;
            auto it = std::lower_bound(ALL(pos[mx]), l);
            std::vector<std::pair<int, int>> inv;
            int lst = l;
            while(it != pos[mx].end()){
                int p = *it;
                if(p > r) break;
                if(p > lst){
                    inv.push_back({lst, p - 1});
                }
                lst = p + 1;
            }
            if(lst <= r) inv.push_back({lst, r});
            for(auto [_l, _r] : inv){
                res += _r - _l + 1;
                res += self(self, _l, _r);
            }

            return res;
        };

        std::cout << dfs(dfs, 1, n) << endl;
    }

    return 0;
}

Details

Tip: Click on the bar to expand more detailed information

Test #1:

score: 0
Time Limit Exceeded

input:

4
2
1 2
2
2 2
7
1 1 1 2 2 2 2
3
1 2 3

output:


result: