Submission #1252655

#TimeUsernameProblemLanguageResultExecution timeMemory
1252655SamAndTriple Peaks (IOI25_triples)C++20
76.53 / 100
453 ms21572 KiB
#include "triples.h"
#include <bits/stdc++.h>
using namespace std;
#define m_p make_pair
#define all(x) (x).begin(),(x).end()
#define sz(x) ((int)(x).size())
#define fi first
#define se second
typedef long long ll;
mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count());
mt19937 rnf(2106);
const int N = 200005, S = 800;

int n;
int h[N];

int aa[3], bb[3];
bool stg(int i, int j, int k)
{
    assert(1 <= i && i < j && j < k && k <= n);
    aa[0] = h[i];
    aa[1] = h[j];
    aa[2] = h[k];
    bb[0] = j - i;
    bb[1] = k - j;
    bb[2] = k - i;
    sort(aa, aa + 3);
    sort(bb, bb + 3);
    return (aa[0] == bb[0] && aa[1] == bb[1] && aa[2] == bb[2]);
}

vector<int> v[N], vv[N];
long long count_triples(std::vector<int> H)
{
    n = sz(H);
    for (int i = 1; i <= n; ++i)
        h[i] = H[i - 1];

    ll ans = 0;
    for (int i = 1; i <= n; ++i)
    {
        int k = i + h[i];
        if (k > n)
            continue;
        if (h[k] >= h[i])
            continue;
        int j1 = i + h[k];
        if (stg(i, j1, k))
            ++ans;
        int j2 = k - h[k];
        if (j1 != j2 && stg(i, j2, k))
            ++ans;
    }
    for (int k = 1; k <= n; ++k)
    {
        int i = k - h[k];
        if (i < 1)
            continue;
        if (h[i] >= h[k])
            continue;
        int j1 = k - h[i];
        if (stg(i, j1, k))
            ++ans;
        int j2 = i + h[i];
        if (j1 != j2 && stg(i, j2, k))
            ++ans;
    }

    for (int i = 1; i <= n; ++i)
    {
        if (i + h[i] <= n)
            v[i + h[i]].push_back(i);
    }
    for (int k = 1; k <= n; ++k)
    {
        if (k - h[k] >= 1)
            vv[k - h[k]].push_back(k);
    }

    for (int x = 1; x <= n; ++x)
    {
        for (int t = 0; t < sz(v[x]); ++t)
        {
            int i = v[x][t];
            int k = x + h[x] - h[i];
            int j = x;
            assert(1 <= i && i < j);
            if (j < k && k <= n)
            {
                if (h[j] > h[i] && h[j] > h[k] && stg(i, x, k))
                    ++ans;
            }
        }
        if (sz(v[x]) + sz(vv[x]) < S)
        {
            for (int t = 0; t < sz(v[x]); ++t)
            {
                for (int tt = 0; tt < sz(vv[x]); ++tt)
                {
                    int i = v[x][t];
                    int k = vv[x][tt];
                    int j = i + h[k];
                    assert(1 <= i && i < j && j < k && k <= n);
                    if (h[j] > h[i] && h[j] > h[k] && stg(i, j, k))
                        ++ans;
                }
            }
        }
        else
        {
            for (int j = 1; j <= n; ++j)
            {
                int hi = h[j] - j + x;
                if (hi % 2 != 0)
                    continue;
                hi /= 2;
                int hk = h[j] - hi;
                if (hi < 1 || hk < 1)
                    continue;
                int i = j - hk;
                int k = j + hi;
                if (1 <= i && k <= n && h[j] > h[k] && h[j] > h[i] && stg(i, j, k))
                    ++ans;
            }
        }
    }

    for (int j = 1; j <= n; ++j)
    {
        if (h[j] % 2 == 0)
        {
            int i = j - h[j] / 2;
            int k = j + h[j] / 2;
            if (1 <= i && k <= n && h[j] > h[i] && h[j] > h[k] && stg(i, j, k))
                --ans;
        }
    }

    return ans;
}

std::vector<int> construct_range(int M, int K)
{
    int n = M;
    vector<int> h(n);
    for (int i = 0; i < n; ++i)
    {
        if (i % 2 == 0)
            h[i] = 1;
        else
        {
            if ((i / 2) % 2 == 0)
                h[i] = 2;
            else
                h[i] = 3;
        }
    }
    //cout << count_triples(h) << "\n";
    return h;
}
#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...