Submission #985937

#TimeUsernameProblemLanguageResultExecution timeMemory
985937MateiKing80늑대인간 (IOI18_werewolf)C++14
0 / 100
4062 ms32520 KiB
#include <bits/stdc++.h>
#include "werewolf.h"

using namespace std;

#define all(a) (a).begin(), (a).end()

const int NMAX = 2e5, MMAX = 4e5;
vector<int> vec[NMAX + 5];

struct DSU
{
    int n;
    vector<int> papa;

    DSU(int N)
    {
        papa.resize(N + 1);
        for(int i = 1; i <= N; i ++)
            papa[i] = i;
        n = N;
    }

    int real_papa(int nod)
    {
        if(papa[nod] == nod)
            return nod;
        return papa[nod] = real_papa(papa[nod]);
    }

    bool query(int u, int v)
    {
        return real_papa(u) == real_papa(v);
    }

    void join(int u, int v)
    {
        papa[real_papa(v)] = real_papa(u);
    }
};

struct Arbore
{
    vector<int> adanc;
    vector<vector<int>> lift, vec;
    int n, bitMax, root;

    Arbore(int N, int ROOT)
    {
        n = N;
        vec.resize(N + 1);
        bitMax = 20;
        root = ROOT;
    }

    void add_edge(int u, int v)
    {
        vec[u].push_back(v);
        vec[v].push_back(u);
    }

    void dfs_lca(int nod, int papa)
    {
        lift[0][nod] = papa;
        adanc[nod] = adanc[papa] + 1;
        for(auto i : vec[nod])
            if(i != papa)
                dfs_lca(i, nod);
    }

    void make_lca()
    {
        lift.resize(bitMax, vector<int> (n + 1));
        adanc.resize(n + 1, 0);
        dfs_lca(root, 0);
        for(int i = 1; i < bitMax; i ++)
            for(int j = 1; j <= n; j ++)
                lift[i][j] = lift[i - 1][lift[i - 1][j]];
    }

    int lca(int u, int v)
    {
        int bit = bitMax - 1;
        if(adanc[u] < adanc[v])
            swap(u, v);
        while(bit >= 0)
        {
            if(adanc[lift[bit][u]] >= adanc[v])
                u = lift[bit][u];
            bit --;
        }
        if(u == v)
            return u;
        bit = bitMax - 1;
        while(bit >= 0)
        {
            if(lift[bit][u] != lift[bit][v])
                u = lift[bit][u], v = lift[bit][v];
            bit --;
        }
        return lift[0][v];
    }

    void dfs_order(int nod, int papa, vector<int> &ord, vector<pair<int, int>> &subTree)
    {
        ord.push_back(nod);
        subTree[nod].first = ord.size() - 1;
        for(auto i : vec[nod])
            if(i != papa)
                dfs_order(i, nod, ord, subTree);
        subTree[nod].second = ord.size() - 1;
    }

    vector<pair<int, int>> preOrder()
    {
        vector<int> ord(1, 0);
        vector<pair<int, int>> subTree(n + n);
        dfs_order(root, 0, ord, subTree);
        return subTree;
    }
};

struct Fenwick
{
    vector<int> aib;
    int n;

    Fenwick(int N)
    {
        n = N;
        aib.resize(N + 1);
    }

    inline int lsb(int x)
    {
        return x & -x;
    }

    void update(int pos, int val)
    {
        while(pos <= n)
        {
            aib[pos] += val;
            pos += lsb(pos);
        }
    }

    int query(int pos)
    {
        int ans = 0;
        while(pos)
        {
            ans += aib[pos];
            pos -= lsb(pos);
        }
        return ans;
    }
};

struct ura
{
    int pos, val, index, inm;
};

bool operator < (ura a, ura b)
{
    return a.val < b.val;
}

vector<int> check_validity_smart(int n, vector<int> u, vector<int> v, vector<int> s, vector<int> f, vector<int> l, vector<int> r)
{
    int m = u.size(), q = s.size();
    vector<vector<int>> vec(n + 1);
    for(int i = 0; i < m; i ++)
        vec[u[i] + 1].push_back(v[i] + 1), vec[v[i] + 1].push_back(u[i] + 1);
    for(int i = 0; i < q; i ++)
        s[i] ++, f[i] ++, l[i] ++, r[i] ++;

    DSU dsuOm(n), dsuLup(n);
    Arbore om(n, 1), lup(n, n);
    for(int i = n; i; i --)
    {
        for(auto j : vec[i])
            if(j >= i && !dsuOm.query(i, j))
            {
                om.add_edge(dsuOm.real_papa(i), dsuOm.real_papa(j));
                dsuOm.join(i, j);
            }
    }
    for(int i = 1; i <= n; i ++)
    {
        for(auto j : vec[i])
            if(j <= i && !dsuLup.query(i, j))
            {
                lup.add_edge(dsuLup.real_papa(i), dsuLup.real_papa(j));
                dsuLup.join(i, j);
            }
    }
    om.make_lca(), lup.make_lca();

    auto ordOm = om.preOrder(), ordLup = lup.preOrder();
    vector<int> ans(q), posLupSchimbat(n + 1);
    Fenwick aib(n);

    for(int i = 1; i <= n; i ++)
        posLupSchimbat[ordOm[i].first] = ordLup[i].first;

    vector<ura> aux;

    for(int i = 0; i < q; i ++)
    {
        if(om.lca(s[i], l[i]) == l[i] && lup.lca(f[i], r[i]) == r[i])
        {
            aux.push_back({ordLup[r[i]].second, ordOm[l[i]].second, i, 1});
            aux.push_back({ordLup[r[i]].second, ordOm[l[i]].first - 1, i, -1});
            aux.push_back({ordLup[r[i]].first - 1, ordOm[l[i]].second, i, -1});
            aux.push_back({ordLup[r[i]].first - 1, ordOm[l[i]].first - 1, i, 1});
        }
    }

    sort(all(aux));
    int p = 0;
    for(int i = 0; i <= n; i ++)
    {
        while(p < aux.size() && aux[p].val == i)
            ans[aux[p].index] += aib.query(aux[p].pos) * aux[p].inm, p ++;
        if(i != n)
            aib.update(posLupSchimbat[i + 1], 1);
    }

    for(int i = 0; i < q; i ++)
        ans[i] = ans[i] != 0;

    return ans;
}

void dfs_mai_mare(int nod, int l, vector<vector<int>> &vec, vector<bool> &viz)
{
    if(viz[nod] || nod < l)
        return;
    viz[nod] = true;
    for(auto i : vec[nod])
        dfs_mai_mare(i, l, vec, viz);
}

void dfs_mai_mic(int nod, int r, vector<vector<int>> &vec, vector<bool> &viz)
{
    if(viz[nod] || nod > r)
        return;
    viz[nod] = true;
    for(auto i : vec[nod])
        dfs_mai_mare(i, r, vec, viz);
}

vector<int> check_validity(int n, vector<int> u, vector<int> v, vector<int> s, vector<int> f, vector<int> l, vector<int> r)
{
    vector<vector<int>> vec(n);
    for(int i = 0; i < u.size(); i ++)
        vec[u[i]].push_back(v[i]), vec[v[i]].push_back(u[i]);
    vector<int> ans;
    for(int i = 0; i < s.size(); i ++)
    {
        ans.push_back(0);
        vector<bool> viz1(n, false), viz2(n, false);
        dfs_mai_mare(s[i], l[i], vec, viz1);
        dfs_mai_mic(f[i], r[i], vec, viz2);
        for(int i = 0; i < n; i ++)
            if(viz1[i] == 1 && viz2[i] == 1)
                ans.back() = 1;
    }
    return ans;
}

/*
6 6 3
5 1
1 2
1 3
3 4
3 0
5 2
4 2 1 2
4 2 2 2
5 4 3 4
*/

Compilation message (stderr)

werewolf.cpp: In function 'std::vector<int> check_validity_smart(int, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>)':
werewolf.cpp:225:17: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<ura>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  225 |         while(p < aux.size() && aux[p].val == i)
      |               ~~^~~~~~~~~~~~
werewolf.cpp: In function 'std::vector<int> check_validity(int, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>, std::vector<int>)':
werewolf.cpp:258:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  258 |     for(int i = 0; i < u.size(); i ++)
      |                    ~~^~~~~~~~~~
werewolf.cpp:261:22: warning: comparison of integer expressions of different signedness: 'int' and 'std::vector<int>::size_type' {aka 'long unsigned int'} [-Wsign-compare]
  261 |     for(int i = 0; i < s.size(); i ++)
      |                    ~~^~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...