Submission #440052

#TimeUsernameProblemLanguageResultExecution timeMemory
440052VladMDuathlon (APIO18_duathlon)C++14
10 / 100
1095 ms1048580 KiB
#include <bits/stdc++.h>

using namespace std;

#define DIM 100007

long long res, cnt[DIM], sz[2*DIM], pnt[2*DIM], n, m, u, v, vis[2*DIM], used[DIM], tin[DIM], tmin[DIM], timer, comps;

set<long long> vec[2*DIM];

set<long long> p;

vector<pair<long long, long long> > edge;

void dfs(long long v, long long par)
{
    used[v]=1;
    tin[v]=tmin[v]=++timer;
    long long ch_cnt=0;
    for(auto to : vec[v])
    {
        if(to==par) continue;
        if(used[to]==0)
        {
            dfs(to, v);
            ch_cnt++;
            tmin[v]=min(tmin[v], tmin[to]);
            if(par!=-1 && tmin[to]>=tin[v])
            {
                p.insert(v);
                pnt[v]=1;
            }
        }
        else tmin[v]=min(tmin[v], tin[to]);
    }
    if(par==-1 && ch_cnt>1)
    {
        p.insert(v);
        pnt[v]=1;
    }
    return;
}

void find_comp(long long v)
{
    vis[v]=comps;
    cnt[comps]++;
    for(auto to : vec[v])
    {
        if(vis[to]!=0) continue;
        find_comp(to);
    }
    return;
}

void buildtree(long long v, long long par)
{
    if(v<=n) sz[v]+=1;
    sz[v]+=cnt[v-n];
    for(auto to : vec[v])
    {
        if(to==par) continue;
        sz[to]+=sz[v];
        buildtree(to, v);
    }
    return;
}

void get_res(long long v)
{
    for(int i=1; i<=2*n; i++) sz[i]=0;
    buildtree(v, -1);
    /*printf("%lld:\n", v);
    for(int i=1; i<=2*n; i++) printf("%lld ", sz[i]);
    printf("\n");*/
    for(auto u : p)
    {
        if(sz[u]<2 || u==v) continue;
        res+=sz[v]*(sz[u]-2);
    }
    for(int i=1; i<=comps; i++)
    {
        if(sz[i+n]<2 || i+n==v) continue;
        res+=sz[v]*(sz[i+n]-2)*cnt[i];
    }
    long long ns=vec[v].size();
    for(int i=0; i<ns; i++)
    {
        res+=sz[v]*(sz[v]-1);
    }
    res+=sz[v]*(sz[v]-1)*(sz[v]-2);
    return;
}

int main()
{
    scanf("%lld%lld", &n, &m);
    for(int i=0; i<m; i++)
    {
        scanf("%lld%lld", &u, &v);
        vec[v].insert(u);
        vec[u].insert(v);
    }
    for(int i=1; i<=n; i++)
    {
        if(used[i]==0) dfs(i, -1);
    }
    for(auto v : p)
    {
        for(auto to : vec[v])
        {
            vec[to].erase(v);
            edge.push_back({v, to});
        }
        vec[v].clear();
    }
    for(int i=1; i<=n; i++)
    {
        if(vis[i]==0 && pnt[i]==0)
        {
            comps++;
            find_comp(i);
        }
    }
    for(auto P : edge)
    {
        v=P.first;
        u=P.second;
        if(pnt[u])
        {
            vec[v].insert(u);
            vec[u].insert(v);
            continue;
        }
        vec[v].insert(vis[u]+n);
        vec[vis[u]+n].insert(v);
    }
    for(auto u : p) get_res(u);
    for(int i=1; i<=comps; i++) get_res(i+n);
    printf("%lld", res);
    return 0;
}

Compilation message (stderr)

count_triplets.cpp: In function 'int main()':
count_triplets.cpp:97:10: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
   97 |     scanf("%lld%lld", &n, &m);
      |     ~~~~~^~~~~~~~~~~~~~~~~~~~
count_triplets.cpp:100:14: warning: ignoring return value of 'int scanf(const char*, ...)' declared with attribute 'warn_unused_result' [-Wunused-result]
  100 |         scanf("%lld%lld", &u, &v);
      |         ~~~~~^~~~~~~~~~~~~~~~~~~~
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...
#Verdict Execution timeMemoryGrader output
Fetching results...