제출 #1333049

#제출 시각아이디문제언어결과실행 시간메모리
1333049aaaaaaaaMoney (IZhO17_money)C++20
25 / 100
213 ms2020 KiB
#include <bits/stdc++.h>
using namespace std;

#define int long long
const int MOD1 = 1e9 + 9;
const int MOD2 = 998244353;

struct pair_hash {
    template <class T1, class T2>
    std::size_t operator() (const std::pair<T1, T2>& pair) const {
        auto hash1 = std::hash<T1>{}(pair.first);
        auto hash2 = std::hash<T2>{}(pair.second);
        return hash1 ^ (hash2 << 1);
    }
};

struct sub_hash
{
    vector<int> dp1, dp2, inv1, inv2;

    int pw(int n, int k, int m){
        int ans = 1;
        while(k > 0){
            if(k & 1) ans = (ans * n) % m;
            n = (n * n) % m;
            k >>= 1;
        }
        return ans;
    }

    pair<int, int> query(int i, int j){
        int f = (dp1[j + 1] - dp1[i] + MOD1) % MOD1 * inv1[i] % MOD1;
        int s = (dp2[j + 1] - dp2[i] + MOD2) % MOD2 * inv2[i] % MOD2;
        return {f, s};
    }

    void init(vector<int> vec){
        int p = 31, p1 = 1, p2 = 1, n = (int) vec.size();
        dp1.resize(n + 5);
        dp2.resize(n + 5);
        inv1.resize(n + 5);
        inv2.resize(n + 5);
        for(int i = 0; i < n; ++i){
            dp1[i + 1] = (dp1[i] + (vec[i] - '0' + 1) * p1 % MOD1) % MOD1;
            dp2[i + 1] = (dp2[i] + (vec[i] - '0' + 1) * p2 % MOD2) % MOD2;
            p1 = p1 * p % MOD1;
            p2 = p2 * p % MOD2;
        }
        inv1[n - 1] = pw(pw(p, n - 1, MOD1), MOD1 - 2, MOD1);
        inv2[n - 1] = pw(pw(p, n - 1, MOD2), MOD2 - 2, MOD2);
        for(int i = n - 2; i >= 0; --i){
            inv1[i] = inv1[i + 1] * p % MOD1;
            inv2[i] = inv2[i + 1] * p % MOD2;
        }
    }

} hsh_srt, hsh_on;

signed main(){
    ios::sync_with_stdio(0);
    cin.tie(0);

    int n, ans = 0;
    cin >> n;

    vector<int> a(n, 0), srt(n, 0);

    for(int i = 0; i < n; ++i){
        cin >> a[i];
        srt[i] = a[i];
    }

    sort(srt.begin(), srt.end());



    int remov = 0;

    while(remov != n){
        hsh_on.init(a);
        hsh_srt.init(srt);

        map<pair<int, int>, pair<int, int>> mp;

        for(int i = 0; i < (int) srt.size(); ++i){
            for(int j = i; j < (int) srt.size(); ++j){
                mp[hsh_srt.query(i, j)] = {i, j};
            }
        }

        int i = (int) a.size() - 1, j = (int) a.size() - 1;
        int st = 0, en = (int) a.size() - 1;

        pair<int, int> rem;

        while(st <= en){
            int mid = st + (en - st) / 2;
            pair<int, int> qry = hsh_on.query(mid, (int) a.size() - 1);
            if(mp.count(qry)){
                j = mid;
                en = mid - 1;
                rem = mp[qry];
            }else{
                st = mid + 1;
            }
        }

        vector<int> new_arr;

        for(int i = 0; i < rem.first; ++i){
            new_arr.push_back(srt[i]);
        }

        for(int i = rem.second + 1; i < (int) a.size(); ++i){
            new_arr.push_back(srt[i]);
        }

        ans += 1, remov += rem.second - rem.first + 1;

        int k = rem.second - rem.first + 1;

        while(k--){
            a.pop_back();
        }

        swap(new_arr, srt);
    }

    cout << ans << "\n";

    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...