Submission #1252632

#TimeUsernameProblemLanguageResultExecution timeMemory
1252632ollelapTriple Peaks (IOI25_triples)C++20
38.87 / 100
1236 ms103328 KiB
#pragma GCC optimize ("O3")

#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) {
        if (!(i < j && j < k)) return false;
        int a[3] = {j-i, k-i, k-j};
        int b[3] = {arr[i], arr[j], arr[k]};

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


    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;
                if (i == j || i == k || j == k) continue;
                int x[] = {i, j, k};
                sort(x, x+3);
                
                if (valid(x[0], x[1], x[2])) ans_s.insert({x[0],x[1],x[2]});
            }
        }
    }


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

    vector<int> before_cnt(n, 0), after_cnt(n, 0);

    rep(b,0,n) {
        before_cnt[b] = cand_before[arr[b]-b+n].size();
        cand_before[arr[b]-b+n].push_back(b);
    }
    for (int b = n-1; b >= 0; b--) {
        after_cnt[b] = cand_after[arr[b]+b].size();
        cand_after[arr[b]+b].push_back(b);
    }

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

    for (auto [a, b, c] : ans_s) {
        assert(valid(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) res[i] = 1 + (rand() % (M-1));

    rep(iter,0,100) {
        int i = rand() % M;
        for (int j = 0; j < res[i]; j++) {
            if (i + j < M) {
                if (rand() % 5) res[i+j] = res[i] - j;
            }
            if (i - j >= 0) {
                if (rand() % 5) res[i-j] = res[i] - j;
            }
        }        
    }

    
    
    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...