제출 #1359553

#제출 시각아이디문제언어결과실행 시간메모리
1359553notbraining역사적 조사 (JOI14_historical)C++20
15 / 100
4093 ms10612 KiB
//https://oj.uz/problem/view/JOI14_historical
#include<iostream>
#include<vector>
#include<set>
#include<map>
#include<unordered_map>
#include<iomanip>
#include <cassert>
#include<algorithm>
#include<queue>
#include <array>
#include<queue>
#include <bitset>
#include<numeric>
#include<random>
using namespace std;
#define int long long
#define pii pair<int,int>
int INF = 1e18;
const int B = 400;
int32_t main(){
    cin.tie(0)->sync_with_stdio(0);
    int n, q; cin >> n >> q;
    vector<int>v(n + 1);
    vector<pii>uncomp;
    vector<int>real_val(n + 1);
    for(int i = 1 ; i <= n; ++i){
        cin >> v[i];
        uncomp.push_back({v[i], i});
    }
    sort(uncomp.begin(), uncomp.end());
    for(auto [val, ind] : uncomp){
        int compressed_value = lower_bound(uncomp.begin(), uncomp.end(), pii{val, 0}) - uncomp.begin();
        real_val[compressed_value] = val;
        v[ind] = compressed_value;
    }
    vector<int>ans(q);
    //sort queries by l/B, r, l, query
    vector<pair<pii, pii>>queries(q);
    for(int i = 0; i < q; ++i){
        int l, r; cin >> l >> r;
        queries[i] = {{l / B, r}, {l, i}};
    }
    sort(queries.begin(), queries.end());
    int l = 0;
    int r = 0;
    int last_block = -1;
    vector<pii>stak;
    vector<int>freq(n + 1);
    vector<int>brute_v(n + 1);
    int cur = 0;


    auto extend_right = [&](){
        r++;
        freq[v[r]]++;
        cur = max(cur, real_val[v[r]] * freq[v[r]]);
        };
    auto extend_left = [&](){
        //save yourself, then extend left
        stak.push_back({v[l - 1], cur});
        --l;
        freq[v[l]]++;
        cur = max(cur, real_val[v[l]] * freq[v[l]]);
        };
    auto roll_back = [&](){
        ++l;
        freq[stak.back().first]--;
        cur = stak.back().second;
        stak.pop_back();
        };

    for(auto qu : queries){
        auto [b_num, qr] = qu.first;
        auto [ql, ind] = qu.second;
        if(last_block != b_num){
            stak.clear();
            l = B * (b_num + 1);
            r = l - 1;
            cur = 0;
            freq = vector<int>(n + 1, 0);
        }
        if(ql / B == qr / B){
            //brute force the answer
            int brute_ans = 0;
            for(int i = ql; i <= qr; ++i){
                brute_v[v[i]]++;
                brute_ans = max(brute_ans, brute_v[v[i]] * real_val[v[i]]);
            }
            ans[ind] = brute_ans;
            for(int i = ql; i <= qr; ++i){
                brute_v[v[i]]--;
            }
        } else{
            //extend right
            while(r < qr){
                extend_right();
            }
            while(ql < l){
                extend_left();
            }
            ans[ind] = cur;
            while(!stak.empty()){
                roll_back();
            }
        }
    }

    for(int i : ans){
        cout << i << "\n";
    }

}
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…
#결과 실행 시간메모리채점기 출력
결과를 불러오는 중입니다…