제출 #1120301

#제출 시각아이디문제언어결과실행 시간메모리
1120301matei__bDuathlon (APIO18_duathlon)C++17
0 / 100
188 ms42392 KiB
#include <bits/stdc++.h>
#include <ext/pb_ds/assoc_container.hpp> 
#include <ext/pb_ds/tree_policy.hpp> 
#define ll long long
#define ull unsigned long long
#define ld long double
#define chad char
#define mod 1'000'000'007
#define dim 100005
#define lim 1000000
#define BASE 31
#define NMAX 21'005
#define FOR(i,a,b) for(int i=(a); i<=(b); i++)
#define ordered_set tree<int, null_type,less<int>, rb_tree_tag,tree_order_statistics_node_update> 
#define pii pair<int,int>
#define pb push_back
#define mp make_pair
#define nr_biti __builtin_popcount
using namespace __gnu_pbds; 
using namespace std;

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

int t=1;
ull n,m;
vector<int> g[dim];
vector<int> gt[dim];
int low[dim],tin[dim];
bool viz[dim];
int timer;
unordered_map<int,bool> is_bridge[dim];

void dfs(int nod,int daddy=0)
{
    viz[nod]=1;
    low[nod]=tin[nod]=++timer;

    for(auto it:g[nod])
    {
        if(it==daddy)
            continue;

        if(viz[it])
        {
            low[nod]=min(low[nod],tin[it]);
        }
        else 
        {
            dfs(it,nod);
            low[nod]=min(low[nod],low[it]);

            if(low[it]>tin[nod])
                is_bridge[nod][it]=is_bridge[it][nod]=1;
        }
    }
}

int comp[dim],nr;
ull sz_comp[dim];

void dfs1(int nod)
{
    viz[nod]=1;
    comp[nod]=nr;
    sz_comp[nr]++;

    for(auto it:g[nod])
    {
        if(!viz[it] && !is_bridge[nod][it])
            dfs1(it);
    }
}

ull ans;
ull sz[dim];

void dfs2(int nod,int daddy=0)
{
    viz[nod]=1;
    sz[nod]+=sz_comp[nod];
    for(auto it:gt[nod])
    {
        if(it==daddy)
            continue;

        dfs2(it,nod);
        sz[nod]+=sz[it];
    }

    // nu pot sa iau un nod marginal ca start 

    if(sz_comp[nod]>=3)
    {
        // pot sa aleg toate in aceiasi componenta 
        ans+=(sz_comp[nod]*(sz_comp[nod]-1)*(sz_comp[nod]-2));

        // acum pot sa aleg 2 din aceiasi componenta 
        // sa zicem ca vreau sa merg in sus intai 
        // e clar ca nu pot sa iau nodul de legatura ca start (as trece de 2 ori prin el)

        ull add=(sz_comp[nod]-1)*(sz_comp[nod]-1);
        ans+=(2*(n-sz[nod])*add);

        // daca merg in jos 
        // sa zicem ca am mai multi fii f1,f2,f3,...fk
        // in cazul in care imi aleg un capat in unul din acesti fii e imposibil ca celalalt capat sa fie in nodul de 
        // legatura 

        // sa zicem ca am avea sum (sz_comp[nod]-1)*(sz_comp[nod]-1)*sz[f1] + ... 
        // (sz_comp[nod]-1)*(sz_comp[nod]-1)*(sz[nod]-sz_comp[nod])
        ans+=(2*(sz[nod]-sz_comp[nod])*add);

        // acum sa zicem ca aleg un singur nod din componenta mea 
        // pot sa iau unul de sus si unul de jos 
        // adk (sz[nod]-sz_comp[nod])*(n-sz[nod])*sz_comp[nod]
        // pot sa iau 2 noduri din subarbori diferiti ai fiilor
        // sz[f1]*(sz[nod]-sz_comp[nod]-sz[f1]) + ... 

        ans+=(2*(n-sz[nod])*(sz_comp[nod])*(sz[nod]-sz_comp[nod]));
        for(auto it:gt[nod])
        {
            if(it==daddy)
                continue;
            ans+=(sz[it]*(sz[nod]-sz_comp[nod]-sz[it])*sz_comp[nod]);
        } 
    }
    else if(sz_comp[nod]==2)
    {
        ull add=(sz_comp[nod]-1)*(sz_comp[nod]-1);
        ans+=(2*(n-sz[nod])*add);
        ans+=(2*(sz[nod]-sz_comp[nod])*add);

        ans+=(2*(n-sz[nod])*(sz_comp[nod])*(sz[nod]-sz_comp[nod]));
        for(auto it:gt[nod])
        {
            if(it==daddy)
                continue;
            ans+=(sz[it]*(sz[nod]-sz_comp[nod]-sz[it])*sz_comp[nod]);
        }
    }
    else 
    {
        ans+=(2ULL*(n-sz[nod])*(sz_comp[nod])*(sz[nod]-sz_comp[nod]));
        for(auto it:gt[nod])
        {
            if(it==daddy)
                continue;
            ans+=(sz[it]*(sz[nod]-sz_comp[nod]-sz[it])*sz_comp[nod]);
        }
    }
    
}

void solve()
{
    cin >> n >> m;
    for(int i=1; i<=m; i++)
    {
        int x,y;
        cin >> x >> y;
        g[x].pb(y);
        g[y].pb(x);
    }

    ull ans1=0;
    for(int i=1; i<=n; i++)
    {
        if(!viz[i])
            dfs(i);
    }

    for(int i=1; i<=n; i++)
        viz[i]=0;

    for(int i=1; i<=n; i++)
    {
        if(!viz[i])
        {
            ++nr;
            dfs1(i);
        }
    }

    for(int i=1; i<=n; i++)
    {
        for(auto it:g[i])
            if(comp[i]!=comp[it])
                gt[comp[i]].pb(comp[it]);
    }

    for(int i=1; i<=n; i++)
        viz[i]=0;

    for(int i=1; i<=nr; i++)
    {
        if(!viz[i])
        {
            ans=0;
            dfs2(i);
            ans1+=ans;
        }
    }

    cout << ans1;
}

int main()
{
    ios_base::sync_with_stdio(false);
    cin.tie(nullptr);
    cout.tie(nullptr);

    //cin >> t;
    while(t--)
        solve();

    return 0;
}

컴파일 시 표준 에러 (stderr) 메시지

count_triplets.cpp: In function 'void solve()':
count_triplets.cpp:158:19: warning: comparison of integer expressions of different signedness: 'int' and 'long long unsigned int' [-Wsign-compare]
  158 |     for(int i=1; i<=m; i++)
      |                  ~^~~
count_triplets.cpp:167:19: warning: comparison of integer expressions of different signedness: 'int' and 'long long unsigned int' [-Wsign-compare]
  167 |     for(int i=1; i<=n; i++)
      |                  ~^~~
count_triplets.cpp:173:19: warning: comparison of integer expressions of different signedness: 'int' and 'long long unsigned int' [-Wsign-compare]
  173 |     for(int i=1; i<=n; i++)
      |                  ~^~~
count_triplets.cpp:176:19: warning: comparison of integer expressions of different signedness: 'int' and 'long long unsigned int' [-Wsign-compare]
  176 |     for(int i=1; i<=n; i++)
      |                  ~^~~
count_triplets.cpp:185:19: warning: comparison of integer expressions of different signedness: 'int' and 'long long unsigned int' [-Wsign-compare]
  185 |     for(int i=1; i<=n; i++)
      |                  ~^~~
count_triplets.cpp:192:19: warning: comparison of integer expressions of different signedness: 'int' and 'long long unsigned int' [-Wsign-compare]
  192 |     for(int i=1; i<=n; 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...
#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...