Cerinta completa

Daniel loves graphs. He thinks a graph is special if it has the following properties:

  • It is undirected.
  • The length of each edge is .
  • It includes exactly different lovely triplets.

A triplet is a set of different nodes. A triplet is lovely if the minimum distance between each pair of nodes in the triplet is exactly . Two triplets are different if or more of their component nodes are different.

Given and , help Daniel draw a special graph.

Input Format

A single line containing space-separated integers, (the number of different lovely triplets you must have in your graph) and (the required distance between each pair of nodes in a lovely triplet), respectively.

Constraints

Output Format

For the first line, print space-separated integers, (the number of nodes in the graph) and (the number of edges in the graph), respectively.
On each line of the subsequent lines, print two space-separated integers, and , describing an edge between nodes and .

Your output must satisfy the following conditions:

If there is more than one correct answer, print any one of them.

Sample Input

3 2

Sample Output

7 7
1 2
2 3
3 4
4 5
5 6
6 1
1 7

Explanation

There are exactly lovely triplets in this graph: , , and .

Observe that each node in a lovely triplet is edges away from the other nodes composing the lovely triplet.


Limbajul de programare folosit: cpp14

Cod:

/* nice editorial !! */

#include <bits/stdc++.h>

//#define debug
#define fie(i,start,stop) for ( int i = start ; i < stop ; i ++ )
#define f first
#define s second
#define pii pair < int , int >
#define vpii vector < pii >
#define vi vector < int >
#define pb push_back
#define mp make_pair

using namespace std ;

vpii nc3 ;
vi x ( 5001 , INT_MAX ) ;
vi y ( 5001 , INT_MAX ) ;
vi z ( 5001 , INT_MAX ) ;
vpii dp ( 5001 , mp ( INT_MAX , INT_MAX ) ) ;
int nc3_size = 0 ;
int p , d , n = 0 , m = 0 ;
vpii edges ( 100 ) ;
int l , mid , r ;

void build_even ()
{
    #ifdef debug
        cout << "building even" << endl ;
    #endif
    int root = n + 1 ;
    int nodes = ( d - 2 ) / 2 ;

    edges [ m ].f = n + 1 ;
    edges [ m ++ ].s = n + 2 ;
    fie ( i , 0 , nodes - 1 )
    {
        edges [ m ].f = n + i + 2 ;
        edges [ m ++ ].s = n + i + 3 ;
    }
    n += nodes + 1 ;
    l = n ;

    edges [ m ].f = root ;
    edges [ m ++ ].s = n + 1 ;
    fie ( i , 0 , nodes - 1 )
    {
        edges [ m ].f = n + i + 1 ;
        edges [ m ++ ].s = n + i + 2 ;
    }
    n += nodes ;
    mid = n ;

    edges [ m ].f = root ;
    edges [ m ++ ].s = n + 1 ;
    fie ( i , 0 , nodes - 1 )
    {
        edges [ m ].f = n + i + 1 ;
        edges [ m ++ ].s = n + i + 2 ;
    }
    n += nodes ;
    r = n ;
}

void build_odd ()
{
    #ifdef debug
        cout << "building odd" << endl ;
    #endif
    if ( d == 3 )
    {
        edges [ m ].f = n + 1 ;
        edges [ m ++ ].s = n + 2 ;
        edges [ m ].f = n + 1 ;
        edges [ m ++ ].s = n + 3 ;
        edges [ m ].f = n + 2 ;
        edges [ m ++ ].s = n + 3 ;
        l = n + 1 ;
        mid = n + 2 ;
        r = n + 3 ;
        n += 3 ;
        return ;
    }

    int nodes = ( d - 3 ) / 2 ;

    int root1 = n + 1 ;
    edges [ m ].f = n + 1 ;
    edges [ m ++ ].s = n + 2 ;
    fie ( i , 0 , nodes - 1 )
    {
        edges [ m ].f = n + i + 2 ;
        edges [ m ++ ].s = n + i + 3 ;
    }
    n += nodes + 1 ;
    l = n ;

    int root2 = n + 1 ;
    edges [ m ].f = n + 1 ;
    edges [ m ++ ].s = n + 2 ;
    fie ( i , 0 , nodes - 1 )
    {
        edges [ m ].f = n + i + 2 ;
        edges [ m ++ ].s = n + i + 3 ;
    }
    n += nodes + 1 ;
    mid = n ;

    int root3 = n + 1 ;
    edges [ m ].f = n + 1 ;
    edges [ m ++ ].s = n + 2 ;
    fie ( i , 0 , nodes - 1 )
    {
        edges [ m ].f = n + i + 2 ;
        edges [ m ++ ].s = n + i + 3 ;
    }
    n += nodes + 1 ;
    r = n ;

    edges [ m ].f = root1 ;
    edges [ m ++ ].s = root2 ;
    edges [ m ].f = root1 ;
    edges [ m ++ ].s = root3 ;
    edges [ m ].f = root2 ;
    edges [ m ++ ].s = root3 ;
}

void add_edge ( int no_l , int no_mid , int no_r )
{
    #ifdef debug
        cout << "adding edge " << no_l << " " << no_mid << " " << no_r << endl ;
    #endif
    if ( d % 2 )
    {
        build_odd () ;
    }
    else
    {
        build_even () ;
    }
    fie ( i , 0 , no_l )
    {
        edges [ m ].f = l ;
        edges [ m ++ ].s = n + i + 1 ;
    }
    n += no_l ;
    fie ( i , 0 , no_mid )
    {
        edges [ m ].f = mid ;
        edges [ m ++ ].s = n + i + 1 ;
    }
    n += no_mid ;
    fie ( i , 0 , no_r )
    {
        edges [ m ].f = r ;
        edges [ m ++ ].s = n + i + 1 ;
    }
    n += no_r ;
}

void solve ()
{
    while ( p )
    {
        #ifdef debug
            cout << "component of size " << dp [ p ].f << endl ;
        #endif
        add_edge ( x [ dp [ p ].f ] , y [ dp [ p ].f ] , z [ dp [ p ].f ] ) ;
        p -= dp [ p ].f ;
    }
}

void add_edge2 ( int no_of_nodes )
{
    #ifdef debug
        cout << "adding edge for dist 2 " << no_of_nodes << endl ;
    #endif
    fie ( i , 0 , no_of_nodes )
    {
        edges [ m ].f = n + 1 ;
        edges [ m ++ ].s = n + i + 2 ;
    }
    n += no_of_nodes + 1 ;
}

void solve2 ()
{
    int idx = nc3_size - 1 ;
    while ( p )
    {
        if ( nc3 [ idx ].f <= p )
        {
            add_edge2 ( nc3 [ idx ].s ) ;
            p -= nc3 [ idx ].f ;
        }
        else
        {
            idx -- ;
        }
    }
}

void precal ()
{
    fie ( i , 1 , 100 )
    {
        fie ( j , i , 100 )
        {
            if ( i * j > 5000 || i + j > 93 )
            {
                break ;
            }
            fie ( k , j , 100 )
            {
                if ( i * j * k > 5000 || i + j + k > 94 )
                {
                    break ;
                }
                int mul = i * j * k ;
                if ( x [ mul ] == INT_MAX || ( ( x [ mul ] + y [ mul ] + z [ mul ] ) > ( i + j + k ) ) )
                {
                    x [ mul ] = i ;
                    y [ mul ] = j ;
                    z [ mul ] = k ;
                }
            }
        }
    }
    fie ( i , 0 , 5001 )
    {
        fie ( j , 1 , 5001 )
        {
            if ( i + j <= 5000 && x [ j ] != INT_MAX && ( dp [ i + j ].s > dp [ i ].s + x [ j ] + y [ j ] + z [ j ] ) )
            {
                dp [ i + j ].f = j ;
                dp [ i + j ].s = dp [ i ].s + x [ j ] + y [ j ] + z [ j ] ;
            }
        }
    }
    int no = 3 ;
    while ( true )
    {
        int prod = no * ( no - 1 ) * ( no - 2 ) ;
        prod /= 6 ;
        if ( prod <= 5000 )
        {
            nc3.pb ( mp ( prod , no ++ ) ) ;
            #ifdef debug
                //cout << "nc3 " << no - 1 << " " << prod << endl ;
            #endif
        }
        else
        {
            break ;
        }
    }
    nc3_size = nc3.size () ;
}

int main ()
{
    precal () ;
    cin >> p >> d ;
    if ( d == 2 )
    {
        solve2 () ;
    }
    else
    {
        solve () ;
    }
    cout << n << " " << m << endl ;
    fie ( i , 0 , m )
    {
        cout << edges [ i ].f << " " << edges [ i ].s << endl ;
    }

    return 0 ;
}

Scor obtinut: 1.0

Submission ID: 464650213

Link challenge: https://www.hackerrank.com/challenges/lovely-triplets/problem

Lovely Triplets