Submission #1307501

#TimeUsernameProblemLanguageResultExecution timeMemory
1307501cpismylifeOwOThe Potion of Great Power (CEOI20_potion)C++20
100 / 100
831 ms186312 KiB
#include <bits/stdc++.h>

using namespace std;

const long long mod = 1e9 + 7;
const int MaxN = 1e6 + 5;

int n, d;
long long arr[MaxN];
int curPos;
vector<int> tmpplace[MaxN];

struct Change
{
    int curtime1, curtime2, i, pos;
    bool isadd;

    Change() = default;

    Change(int curtime)
    {
        curtime1 = curtime;
        pos = curPos;
        curtime2 = -1;
    }
};

vector<Change> cur[MaxN];
vector<int> nowplace[MaxN];

void init(int N, int D, int H[])
{
    n = N;
    d = D;
    curPos = 0;
    tmpplace[0].clear();
    for (int x = 1; x <= n; x++)
    {
        arr[x] = H[x - 1];
        cur[x].push_back(Change(0));
    }
}

void Add(int u, int v, int d)
{
    vector<int> tmp;
    bool hasadd = false;
    for (int x : nowplace[u])
    {
        if (!hasadd && arr[v] <= arr[x])
        {
            hasadd = true;
            tmp.push_back(v);
        }
        tmp.push_back(x);
    }
    if (!hasadd)
    {
        tmp.push_back(v);
    }
    nowplace[u] = tmp;
    if (~cur[u].back().curtime2)
    {
        curPos++;
        tmpplace[curPos] = tmp;
        cur[u].push_back(Change(d));
        return;
    }
    cur[u].back().curtime2 = d;
    cur[u].back().isadd = true;
    cur[u].back().i = v;
}

void Remove(int u, int v, int d)
{
    vector<int> tmp;
    for (int x : nowplace[u])
    {
        if (x != v)
        {
            tmp.push_back(x);
        }
    }
    nowplace[u] = tmp;
    if (~cur[u].back().curtime2)
    {
        curPos++;
        tmpplace[curPos] = tmp;
        cur[u].push_back(Change(d));
        return;
    }
    cur[u].back().curtime2 = d;
    cur[u].back().isadd = false;
    cur[u].back().i = v;
}

void curseChanges(int U, int A[], int B[])
{
    curPos = 0;
    set<pair<int, int>> s;
    for (int w = 0; w < U; w++)
    {
        int u = A[w] + 1, v = B[w] + 1;
        pair<int, int> tmp = make_pair(min(u, v), max(u, v));
        if (s.find(tmp) == s.end())
        {
            Add(u, v, w + 1);
            Add(v, u, w + 1);
            s.insert(tmp);
        }
        else
        {
            Remove(u, v, w + 1);
            Remove(v, u, w + 1);
            s.erase(tmp);
        }
    }
    for (int x = 1; x <= n; x++)
    {
        nowplace[x].clear();
    }
}

vector<int> aft[2];

int BSearch(int u, int d)
{
    int l = 0, r = (int)cur[u].size() - 1, mid, res = (int)cur[u].size();
    while (l <= r)
    {
        mid = (l + r) / 2;
        if (cur[u][mid].curtime1 <= d)
        {
            res = mid;
            l = mid + 1;
        }
        else
        {
            r = mid - 1;
        }
    }
    return res;
}

void Reconstruct(int id, int u, int d)
{
    int p = BSearch(u, d);
    aft[id].clear();
    if (~cur[u][p].curtime2 && cur[u][p].curtime2 <= d)
    {
        int k = cur[u][p].i;
        if (cur[u][p].isadd)
        {
            bool hasadd = false;
            for (int v : tmpplace[cur[u][p].pos])
            {
                if (!hasadd && arr[k] <= arr[v])
                {
                    aft[id].push_back(k);
                    hasadd = true;
                }
                aft[id].push_back(v);
            }
            if (!hasadd)
            {
                aft[id].push_back(k);
            }
        }
        else
        {
            for (int v : tmpplace[cur[u][p].pos])
            {
                if (v != k)
                {
                    aft[id].push_back(v);
                }
            }
        }
        return;
    }
    aft[id] = tmpplace[cur[u][p].pos];
}

int question(int X, int Y, int V)
{
    int u = X + 1, v = Y + 1, w = V;
    Reconstruct(0, u, w);
    Reconstruct(1, v, w);
    if (aft[0].empty() || aft[1].empty())
    {
        return 1e9;
    }
    int y = 0;
    long long res = 1e9 + 1;
    for (int x = 0; x < (int)aft[0].size(); x++)
    {
        while (y < (int)aft[1].size() && arr[aft[0][x]] > arr[aft[1][y]])
        {
            y++;
        }
        if (y < (int)aft[1].size())
        {
            res = min(res, abs(arr[aft[0][x]] - arr[aft[1][y]]));
        }
        if (y > 0)
        {
            res = min(res, abs(arr[aft[0][x]] - arr[aft[1][y - 1]]));
        }
    }
    return res;
}

#ifdef cpismylifeOwO
int main()
{
    //freopen("POTION.INP", "r", stdin);
    //freopen("POTION.OUT", "w", stdout);
    int N, D, U, Q;
    std::ios::sync_with_stdio(false); std::cin.tie(NULL);
    std::cin >> N >> D >> U >> Q;

    int *F = new int[N];
    for (int i=0; i<N; i++)
    std::cin >> F[i];
    init(N, D, F);

    int *A = new int[U], *B = new int[U];
    for (int i=0; i<U; i++) {
        std::cin >> A[i] >> B[i];
    }
    curseChanges(U, A, B);

    bool correct = true;
    for (int i=0; i<Q; i++) {
    int X,Y,V,CorrectAnswer;
    std::cin >> X >> Y >> V >> CorrectAnswer;
    int YourAnswer = question(X,Y,V);
    if (YourAnswer != CorrectAnswer) {
        std::cout << "WA! Question: " << i
        << " (X=" << X << ", Y=" << Y << ", V=" << V << ") "
        <<  "Your answer: " << YourAnswer
                << " Correct Answer: " << CorrectAnswer << std::endl;
        correct = false;
    } else {
        std::cerr << YourAnswer << " - OK" << std::endl;
    }
    }
    if (correct) {
        std::cout << "Correct." << std::endl;
    } else std::cout << "Incorrect." << std::endl;
    return 0;
}
#endif // cpismylifeOwO
#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...