Submission #1252574

#TimeUsernameProblemLanguageResultExecution timeMemory
1252574ollelapTriple Peaks (IOI25_triples)C++20
13.65 / 100
253 ms47828 KiB
#include "triples.h"

using namespace std;
#include <bits/stdc++.h>

#define rep(i,a,b) for(int i = a; i < b; i++)

long long count_triples(std::vector<int> arr) {
    int n = arr.size();

    auto valid = [&](int i, int j, int k) {
        int a[3] = {abs(i-j), abs(i-k), abs(j-k)};
        int b[3] = {arr[i], arr[j], arr[k]};
        sort(a, a+3);
        sort(b, b+3);

        return (a[0] == b[0] && a[1] == b[1] && a[2] == b[2]);
    };


    set<tuple<int,int,int>> ans_s;

    rep(i,0,n) {
        for (auto j : {i - arr[i], i + arr[i]}) {
            if (j < 0 || j > n-1) continue;

            for (auto k : {j - arr[j], j + arr[j], i - arr[j], i + arr[j]}) {
                if (k < 0 || k > n-1) continue;
                int x[] = {i, j, k};
                sort(x, x+3);
                if (valid(i, j, k)) ans_s.insert({x[0],x[1],x[2]});
            }
        }
    }


    // case 3:
    // a < b < c, arr[a] = c-b, arr[b] = c-a, arr[c] = b-a
    // iterate over b
    // arr[a] - a = c-b-a = arr[b] - b
    // arr[c] + c = b-a+c = arr[b] + b

    vector<int> valid_before(n, 0);
    map<int,vector<int>> cand_before, cand_after;

    rep(b,0,n) cand_before[arr[b]-b].push_back(b);
    rep(b,0,n) cand_after[arr[b]+b].push_back(b);

    rep(b,0,n) {
        int before_cnt, after_cnt;
        
        int low = 0, high = cand_before[arr[b]-b].size(), mid;
        while (high - low > 1) {
            mid = (low + high) / 2;
            if (cand_before[arr[b]-b][mid] < b) low = mid;
            else high = mid;
        }
        before_cnt = high;

        low = 0, high = cand_after[arr[b]+b].size();
        while (high - low > 1) {
            mid = (low + high) / 2;
            if (cand_after[arr[b]+b][mid] < b) low = mid;
            else high = mid;
        }
        after_cnt = cand_after[arr[b]+b].size() - high - 1;

        if (before_cnt < after_cnt) {
            rep(i,0,before_cnt) {
                int a = cand_before[arr[b]-b][i];
                int c = a + arr[b];
                if (valid(a, b, c)) ans_s.insert({a, b, c});
            }
        }
        else {
            rep(i,high+1,cand_after[arr[b]+b].size()) {
                int c = cand_after[arr[b]+b][i];
                int a = c - arr[b];
                if (valid(a, b, c)) ans_s.insert({a, b, c});
            }
        }
    }

    int ans = ans_s.size();
    
    return ans;
}

std::vector<int> construct_range(int M, int K) {
    vector<int> res(M);

    rep(i,0,M/2) res[i] = i+1;
    rep(i,M/2,M) res[i] = 1 + M/2 - (i-M/2);
    
    return res;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...