Submission #238490

# Submission time Handle Problem Language Result Execution time Memory
238490 2020-06-11T14:34:15 Z Vimmer Usmjeri (COCI17_usmjeri) C++14
28 / 140
1236 ms 180060 KB
#include <bits/stdc++.h>
//#include <ext/pb_ds/assoc_container.hpp>
//#include <ext/pb_ds/tree_policy.hpp>

//#pragma GCC optimize("unroll-loops")
//#pragma GCC optimize("-O3")
//#pragma GCC optimize("Ofast")
//#pragma GCC optimize("fast-math")
//#pragma GCC optimize("no-stack-protector")

#define F first
#define S second
#define sz(x) int(x.size())
#define pb push_back
#define N 300001
#define M ll(1e9 + 7)
#define inf 1e9 + 1e9

using namespace std;
//using namespace __gnu_pbds;

typedef long double ld;
typedef long long ll;
typedef short int si;
typedef array <int, 2> a2;

//typedef tree <int, null_type, less_equal<int>, rb_tree_tag, tree_order_statistics_node_update> ordered_set;


vector <array <int, 2> > g[N], gr[N], qr, v[N];

void add(int a, int b, int c)
{
    v[a].pb({b, c});

    v[b].pb({a, c});

}
bool mkr[N];

int pr[N], rk[N], t[N + N][20], in[N], tin[N], id, h[N], logs[N + N], mnr[N], nh[N], mt[N];

int fnd(int x) {if (pr[x] != x) pr[x] = fnd(pr[x]); return pr[x];}

set <pair <int, int> > se;

void link(int x, int y)
{
    if (rk[x] < rk[y]) swap(x, y);

    pr[y] = x;

    rk[x] += rk[y];
}

vector <int> vr, to[N], glub[N], lnk[N], a[N];

ll ans = 1;

array <int, 2> pred[N];

void spusk(int v, int p)
{
    if (p != -1) h[v] = h[p] + 1; else pred[v] = {-1, -1};

    nh[v] = h[v];

    glub[h[v]].pb(v);

    in[v] = sz(vr);

    tin[v] = id++;

    vr.pb(v);

    for (auto it : g[v])
    {
        if (it[0] == p) continue;

        spusk(it[0], v);

        pred[it[0]] = {v, it[1]};

        vr.pb(v);

        gr[v].pb({tin[it[0]], it[1]});
    }

    gr[v].pb({int(1e9), int(1e9)});
}

int lca(int a, int b)
{
    if (in[a] > in[b]) swap(a, b);

    int j = logs[in[b] - in[a] + 1];

    a = t[in[a]][j];

    b = t[in[b] - (1 << j) + 1][j];

    if (h[a] > h[b]) return b;

    return a;
}

void dfser(int nd, int p)
{
    for (auto it : g[nd])
    {
        if (it[0] == p) continue;

        dfser(it[0], nd);

        nh[nd] = min(nh[nd], nh[it[0]]);

        if (nh[it[0]] < h[nd]) add(it[0], nd, 0);
    }
}

bool check(int nd, int c)
{
    if (mt[nd] != -1) return (mt[nd] == c);

    mt[nd] = c;

    for (auto it : v[nd])
    {
        if (!check(it[0], (it[1] ^ c))) return 0;
    }

    return 1;
}
int main()
{
    //freopen("input.txt", "r", stdin); //freopen("output4.txt", "w", stdout);

    ios_base::sync_with_stdio(0); istream::sync_with_stdio(0); cin.tie(0); cout.tie(0);

    int n, m;

    cin >> n >> m;

    for (int i = 2; i < N + N; i++) logs[i] = 1 + logs[i >> 1];

    bool f = 1;

    for (int i = 0; i < n - 1; i++)
    {
        int x, y;

        cin >> x >> y;

        g[x].pb({y, i});

        g[y].pb({x, i});

        pr[i] = i;

        rk[i] = 1;
    }

    for (int i = 1; i <= n; i++) if (sz(g[i]) > 2) f = 0;

    if (f)
    {
            int beg;

            for (int i = 1; i <= n; i++) if (sz(g[i]) == 1) beg = i;

            for (; m > 0 ; m--)
            {
                int x, y;

                cin >> x >> y;

                a[x].pb(m);

                a[y].pb(m);
            }

            vector <int> vr; vr.clear();

            int v = beg, p = -1;

            while (v != -1)
            {
                int nxt = -1;

                vr.pb(v);

                for (auto it : g[v])
                {
                    if (it[0] == p) continue;

                    nxt = it[0];
                }

                p = v;

                v = nxt;
            }

            ll ans = 1;

            set <int> se; se.clear();

            for (int i = 0; i < sz(vr); i++)
            {
                bool f = 1;

                if (i != 0 && sz(se) == 0) {f = 0; ans = (ans + ans) % M;}

                for (auto it : a[vr[i]])
                {
                    if (se.find(it) == se.end()) se.insert(it);
                      else se.erase(it);
                }

                if (i != 0 && f && sz(se) == 0) ans = (ans + ans) % M;
            }
            cout << ans << endl;

            exit(0);
    }

    spusk(1, -1);

    for (int i = 0; i < sz(vr); i++) t[i][0] = vr[i];

    for (int j = 1; j < 20; j++)
        for (int i = 0; i < sz(vr); i++)
        {
            int a = t[i][j - 1];

            int b = t[min(sz(vr) - 1, i + (1 << (j - 1)))][j - 1];

            if (h[a] > h[b]) t[i][j] = b; else t[i][j] = a;
        }

    for (int i = 1; i <= n; i++) mnr[i] = -1;

    for (int i = 0; i < m; i++)
    {
        int x, y;

        cin >> x >> y;

        qr.pb({x, y});

        se.insert({x, y});

        se.insert({y, x});

        int lc = lca(x, y);

        nh[x] = min(nh[x], h[lc]);

        nh[y] = min(nh[y], h[lc]);

        if (lc != x && lc != y) add(x, y, 1);

        if (lc == x) to[y].pb(x);
          else if (lc == y) to[x].pb(y);
            else
            {
                to[x].pb(lc);

                to[y].pb(lc);

                int pos1 = upper_bound(gr[lc].begin(), gr[lc].end(), a2{tin[x], int(1e9)}) - gr[lc].begin() - 1;

                int pos2 = upper_bound(gr[lc].begin(), gr[lc].end(), a2{tin[y], int(1e9)}) - gr[lc].begin() - 1;

                int x = fnd(gr[lc][pos1][1]), y = fnd(gr[lc][pos2][1]);

                if (x != y) link(x, y);
            }
    }

    dfser(0, 0);

    memset(mt, -1, sizeof(mt));

    for (int i = 1; i < n; i++)
    {
        if (mt[i] != -1) continue;

        if (!check(i, 0)) {cout << 0 << endl; exit(0);}
    }

    memset(mkr, 0, sizeof(mkr));

    for (int i = N - 1; i >= 0; i--)
        for (auto v : glub[i])
        {
            int root = -1;

            if (sz(lnk[v]) != 0)
            {
                root = lnk[v][0];

                for (auto it : lnk[v])
                {
                    int x = fnd(root), y = fnd(it);

                    if (x != y) link(x, y);
                }
            }

            int mn = -1;

            for (auto it : to[v])
                if (mn == -1 || h[mn] > h[it]) mn = it;

            if (mnr[v] != -1 && (mn == -1 || h[mn] > h[mnr[v]])) mn = mnr[v];

            if (mn == v || mn == -1) continue;

            int nxt = pred[v][0], nm = pred[v][1];

            if (nxt == -1) continue;

            if (mn != nxt) lnk[nxt].pb(nm);

            if (mnr[nxt] == -1 || h[mnr[nxt]] > h[mn]) mnr[nxt] = mn;

            if (mnr[v] != -1 && mnr[v] != v)
            {
                int x = fnd(root), y = fnd(nm);

                if (x != y) link(x, y);
            }
        }

    for (int i = 0; i < n - 1; i++)
    {
        int id = fnd(i);

        if (mkr[id]) continue;

        mkr[id] = 1;

        ans = (ans + ans) % M;
    }

    cout << ans << endl;
}

Compilation message

usmjeri.cpp: In function 'int main()':
usmjeri.cpp:184:17: warning: 'beg' may be used uninitialized in this function [-Wmaybe-uninitialized]
             int v = beg, p = -1;
                 ^
# Verdict Execution time Memory Grader output
1 Correct 269 ms 65264 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 473 ms 76900 KB Output is correct
# Verdict Execution time Memory Grader output
1 Correct 38 ms 53888 KB Output is correct
2 Incorrect 39 ms 54264 KB Output isn't correct
# Verdict Execution time Memory Grader output
1 Correct 38 ms 53888 KB Output is correct
2 Incorrect 39 ms 54172 KB Output isn't correct
# Verdict Execution time Memory Grader output
1 Correct 46 ms 55672 KB Output is correct
2 Incorrect 49 ms 55032 KB Output isn't correct
# Verdict Execution time Memory Grader output
1 Correct 44 ms 55544 KB Output is correct
2 Incorrect 50 ms 55032 KB Output isn't correct
# Verdict Execution time Memory Grader output
1 Correct 964 ms 173148 KB Output is correct
2 Correct 996 ms 175276 KB Output is correct
3 Incorrect 503 ms 124748 KB Output isn't correct
# Verdict Execution time Memory Grader output
1 Correct 1141 ms 178568 KB Output is correct
2 Correct 1043 ms 178396 KB Output is correct
3 Incorrect 678 ms 138212 KB Output isn't correct
# Verdict Execution time Memory Grader output
1 Correct 1236 ms 179164 KB Output is correct
2 Correct 1213 ms 174100 KB Output is correct
3 Incorrect 705 ms 138472 KB Output isn't correct
# Verdict Execution time Memory Grader output
1 Correct 1065 ms 179420 KB Output is correct
2 Correct 1056 ms 180060 KB Output is correct
3 Incorrect 533 ms 123876 KB Output isn't correct