Cod sursa(job #2840316)

Utilizator toma_ariciuAriciu Toma toma_ariciu Data 27 ianuarie 2022 13:22:16
Problema Lowest Common Ancestor Scor 0
Compilator cpp-64 Status done
Runda Arhiva educationala Marime 2.57 kb
#include <iostream>
#include <fstream>
#include <vector>
#include <cstring>

using namespace std;

#pragma GCC optimize ("Ofast")

ifstream fin("ct.in");
ofstream fout("ct.out");

int teste, n, q, ans, log2, ind;
int rmq[20][200005], depth[100005], e[200005], poz[100005], l2[200005], sus[100005];
vector <int> G[100005], p[100005];
struct liniutza {
    int c1, c2;
}v[100005];
bool mark[100005]; //salut ba mark haha

void dfs_init(int nod, int tata)
{
    e[++ind] = nod;
    poz[nod] = ind;
    depth[nod] = depth[tata] + 1;
    sus[nod] = tata;
    for(int vecin : G[nod])
        if(vecin != tata)
        {
            dfs_init(vecin, nod);
            e[++ind] = nod;
        }
}

void marcare(int nod)
{
    mark[nod] = 1;
    for(int vecin : G[nod])
        if(!mark[vecin] && vecin != sus[nod])
            marcare(vecin);
}

void dfs(int nod)
{
    for(int vecin : G[nod])
        if(vecin != sus[nod])
            dfs(vecin);
    for(int tero : p[nod])
    {
        if(!mark[v[tero].c1] && !mark[v[tero].c2])
        {
            marcare(nod);
            ans++;
        }
    }
}

int lca(int x, int y)
{
    int st, dr, log, ans;
    st = min(poz[x], poz[y]);
    dr = max(poz[x], poz[y]);
    log = l2[dr - st + 1];
    if(depth[rmq[log][st]] < depth[rmq[log][dr - (1 << log) + 1]])
        return rmq[log][st];
    else
        return rmq[log][dr - (1 << log) + 1];
}

void solve()
{
    ans = 0;
    ind = 0;
    fin >> n >> q;
    for(int i = 1; i < n; i++)
    {
        int x, y;
        fin >> x >> y;
        G[x].push_back(y);
        G[y].push_back(x);
    }
    dfs_init(1, 0);
    for(int i = 2; i <= ind; i++)
        l2[i] = l2[i / 2] + 1;
    for(int i = 1; i <= ind; i++)
        rmq[0][i] = e[i];
     for(int j = 1; (1 << j) <= ind; j++)
    {
        for(int i = 1; i - 1 + (1 << j) <= ind; i++)
        {
            if(depth[rmq[j - 1][i]] < depth[rmq[j - 1][i + (1 << (j - 1))]])
                rmq[j][i] = rmq[j - 1][i];
            else
                rmq[j][i] = rmq[j - 1][i + (1 << (j - 1))];
        }
    }
    for(int i = 1; i <= q; i++)
    {
        fin >> v[i].c1 >> v[i].c2;
        int x = lca(v[i].c1, v[i].c2);
        p[x].push_back(i);
    }
    dfs(1);
    fout << ans << '\n';
    for(int i = 1; i <= n; i++)
    {
        G[i].clear();
        p[i].clear();
    }
    memset(rmq, 0, sizeof rmq);
    memset(mark, 0, sizeof mark);
}

int main()
{
    ios::sync_with_stdio(false);
    fin >> teste;
    while(teste--)
        solve();
    return 0;
}