Cod sursa(job #2975977)

Utilizator andu2006Alexandru Gheorghies andu2006 Data 7 februarie 2023 22:18:54
Problema Obiective Scor 70
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 3.89 kb
#include <bits/stdc++.h>
#pragma GCC optimize("unroll-loops")

using namespace std;
typedef int ll;
typedef pair<ll,ll> pll;
const int NMAX=1<<15,LGMAX=15,buffsize=6969;
const long long TL=3e8;
long long startTime;
long long Time(){
    return chrono::steady_clock::now().time_since_epoch().count();
}
ofstream fout("obiective.out");
FILE* fin;
char buff[buffsize];
int buffpos=buffsize;
int read(){
    if(buffpos==buffsize) fread(buff,1,buffsize,fin),buffpos=0;
    int n=0;
    while(buff[buffpos]<'0' || buff[buffpos]>'9'){
        ++buffpos;
        if(buffpos==buffsize) fread(buff,1,buffsize,fin),buffpos=0;
    }
    while(buff[buffpos]>='0' && buff[buffpos]<='9'){
        n=(n<<1)+(n<<3)+(buff[buffpos]^48);
        ++buffpos;
        if(buffpos==buffsize) fread(buff,1,buffsize,fin),buffpos=0;
    }
    return n;
}
ll low[NMAX],tin[NMAX],cid[NMAX],tid=0,cntctc=0;
bool visited[NMAX];
stack<ll> cnd;
vector<ll> edg[NMAX];
vector<ll> ctc_edg[NMAX],ctc_redg[NMAX];
ll indeg[NMAX],depth[NMAX];
ll Link[LGMAX][NMAX],p[LGMAX][NMAX];
void dfs(ll u){
    low[u]=tin[u]=++tid;
    cnd.push(u);
    visited[u]=1;
    for(auto it : edg[u]){
        if(tin[it]==0) dfs(it),low[u]=min(low[u],low[it]);
        else if(visited[it]) low[u]=min(low[u],tin[it]);
    }
    if(tin[u]==low[u]){
        ll x; cntctc++;
        do{
            x=cnd.top();
            cid[x]=cntctc;
            cnd.pop();
            visited[x]=0;
        }while(x!=u);
    }
}
void dfs2(ll u){
    if(Time()-startTime>TL) exit(2);
    for(auto it : ctc_edg[u]){
        if(depth[it]>depth[u]){
            dfs2(it);
            if(depth[Link[0][it]]<depth[Link[0][u]])
                Link[0][u]=Link[0][it];
        }
    }
}
ll LCA(ll u, ll v){
    if(depth[u]<depth[v]) swap(u,v);
    for(ll bit=LGMAX-1;bit>=0;bit--)
        if(depth[u]-(1<<bit)>=depth[v])
            u=p[bit][u];
    if(u==v) return u;
    for(ll bit=LGMAX-1;bit>=0;bit--)
        if(p[bit][u]!=p[bit][v])
            u=p[bit][u],v=p[bit][v];
    return p[0][u];
}
set<pll> ctc_edges;
int main()
{
    startTime=Time();
    ios_base::sync_with_stdio(false);
    fin=fopen("obiective.in","r");
    ll n=read(),m=read();
    for(ll i=0;i<m;i++){
        ll u=read(),v=read();
        edg[u].push_back(v);
    }
    for(ll i=1;i<=n;i++)
        if(tin[i]==0)
            dfs(i);
    for(ll i=1;i<=n;i++){
        for(auto it : edg[i]){
            if(cid[i]!=cid[it] && !ctc_edges.count({i,it})){
                ctc_edges.insert({i,it});
                ctc_edg[cid[i]].push_back(cid[it]);
                ctc_redg[cid[it]].push_back(cid[i]);
                ++indeg[cid[it]];
            }
        }
    }
    for(ll i=1;i<=n;i++)
        Link[0][i]=i;
    for(ll i=1;i<=n;i++) edg[i].clear();
    queue<ll> q;
    ll root=0;
    for(ll i=1;i<=cntctc;i++)
        if(indeg[i]==0)
            q.push(i),depth[i]=0,ctc_redg[i].push_back(0),root=i;

    while(!q.empty()){
        for(auto it : ctc_edg[q.front()]){
            --indeg[it];
            if(indeg[it]==0){
                p[0][it]=q.front();
                depth[it]=depth[q.front()]+1;
                q.push(it);
            }
        }
        q.pop();
    }
    for(ll i=1;i<=cntctc;i++){
        for(auto it : ctc_redg[i]){
            if(depth[it]<depth[Link[0][i]])
                Link[0][i]=it;
        }
    }
    dfs2(root);
    for(ll bit=1;bit<LGMAX;bit++)
        for(ll i=1;i<=cntctc;i++)
            Link[bit][i]=Link[bit-1][Link[bit-1][i]],p[bit][i]=p[bit-1][p[bit-1][i]];
    ll queries=read();
    if(Time()-startTime>TL) return 1;
    while(queries--){
        ll u=read(),v=read(),ans=0;
        u=cid[u],v=cid[v];
        ll w=LCA(u,v);
        if(u!=w){
            for(ll bit=LGMAX-1;bit>=0;bit--){
                if(depth[Link[bit][u]]>depth[w])
                    u=Link[bit][u],ans+=(1<<bit);
            }
            fout<<ans+1<<'\n';
        }
        else fout<<"0\n";
        if(Time()-startTime>TL) return 1;
    }
    return 0;
}