제출 #1248456

#제출 시각아이디문제언어결과실행 시간메모리
1248456chikien2009Port Facility (JOI17_port_facility)C++20
10 / 100
9 ms16200 KiB
#include <bits/stdc++.h>

using namespace std;

void setup()
{
    ios_base::sync_with_stdio(0);
    cin.tie(0);
    cout.tie(0);
}

struct DSU
{
    int par[2000001], sz[2000001];
    inline int Get(int inp)
    {
        return (par[inp] == inp ? inp : par[inp] = Get(par[inp]));
    }
    inline DSU()
    {
        for (int i = 0; i <= 2e6; ++i)
        {
            par[i] = i;
            sz[i] = 1;
        }
    }
    inline void Combine(int ina, int inb)
    {
        ina = Get(ina);
        inb = Get(inb);
        if (ina != inb)
        {
            if (sz[ina] < sz[inb])
            {
                swap(ina, inb);
            }
            sz[ina] += sz[inb];
            par[inb] = ina;
        }
    }
} dsu;

struct SEGMENT_TREE
{
    int tree[8000000];
    inline void Update(int ind, int l, int r, int x, int v)
    {
        if (r < x || x < l)
        {
            return;
        }
        if (l == r)
        {
            tree[ind] = v;
            return;
        }
        int m = (l + r) >> 1;
        Update(ind << 1, l, m, x, v);
        Update(ind << 1 | 1, m + 1, r, x, v);
        tree[ind] = max(tree[ind << 1], tree[ind << 1 | 1]);
    }
    inline int Get(int ind, int l, int r, int x, int y)
    {
        if (r < x || y < l)
        {
            return 0;
        }
        if (x <= l && r <= y)
        {
            return tree[ind];
        }
        int m = (l + r) >> 1;
        return max(Get(ind << 1, l, m, x, y), Get(ind << 1 | 1, m + 1, r, x, y));
    }
} st;

int n, a[2000001], b, res = 1;
const int mod = 1e9 + 7;
set<int> s;
set<int>::iterator l, r;
vector<list<int>> all;
list<int> temp;

int main()
{
    setup();

    cin >> n;
    for (int i = 0, j; i < n; ++i)
    {
        cin >> j >> a[j];
    }
    for (int i = 1; i <= 2 * n; ++i)
    {
        if (a[i] != 0)
        {
            s.insert(a[i]);
            l = s.lower_bound(i);
            r = s.lower_bound(a[i]);
            b = st.Get(1, 1, 2 * n, i, a[i]);
            if (i < b && b < a[i])
            {
                cout << 0;
                return 0;
            }
            if (l != r)
            {
                r = prev(r);
                st.Update(1, 1, 2 * n, a[i], (*r));
            }
        }
    }
    // list::splice() work very fast, read more on internet
    for (int i = 1; i <= 2 * n; ++i)
    {
        if (a[i] != 0)
        {
            all.push_back({{a[i]}});
        }
        else
        {
            temp.clear();
            while (true)
            {
                if (all.back().back() == i)
                {
                    all.back().pop_back();
                    if (all.back().empty())
                    {
                        all.pop_back();
                    }
                    break;
                }
                dsu.Combine(i, all.back().back());
                temp.splice(temp.begin(), all.back());
                all.pop_back();
            }
            if (!temp.empty())
            {
                all.push_back({});
                all.back().splice(all.back().begin(), temp);
            }
        }
    }
    for (int i = 1; i <= 2 * n; ++i)
    {
        if (a[i] != 0 && dsu.Get(a[i]) == a[i])
        {
            (res *= 2) %= mod;
        }
    }
    cout << res;
    return 0;
}
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...