Cod sursa(job #3294840)

Utilizator Cyb3rBoltSbora Ioan-David Cyb3rBolt Data 29 aprilie 2025 13:54:18
Problema Arbori Scor 30
Compilator cpp-64 Status done
Runda Arhiva de probleme Marime 1.87 kb
#include <bits/stdc++.h>

using namespace std;
ifstream fin("arbori.in");
ofstream fout("arbori.out");
#define int long long
int n, mod, rest, dp[110][2];
///dp[i][0] = nr de moduri de a construi un arbore cu i noduri fiecare avand grad = rest (mod mod) unde voi gasii si rasp
///dp[i][1] = nr de moduri de a construi un arbore cu i noduri fiecare avand grad = rest - 1 (mod mod) pt ca daca ma adancesc o muchie
///vine de la parinte si mai tre sa pun decat rest - 1 sa ajung la gradu bun

///practic la dp[i][1] avem radacina frunza si la dp[i][0] avem radacina interna

inline int combi(int n, int k) {
    if(k > n) return 0;
    if(k > n - k) k = n - k;
    int rez = 1;
    for(int i=0; i<k; i++) {
        rez *= (n - i);
        rez /= (i + 1);
    }
    return rez;
}

inline int combiRepet(int n, int k) { return combi(n + k - 1, k); }

inline void backTrack(int nivel, int grad, int sum, int ramas, int total) {
    ///arborele va avea total noduri din care mai am de pus ramas noduri
    ///la fiecare voi incerca sa pun arbori de dimensiune nivel folosindu ma de starile anterioare
    if(ramas == 0) {
        if(grad % mod == rest) dp[total][0] += sum;
        if(grad % mod == (rest - 1 + mod) % mod) dp[total][1] += sum;
    }
    else if(nivel <= ramas) {
        for(int k=0; k * nivel <= ramas; k++) {
            ///adaug k fii/arbori de marime nivel(cu nivel noduri) punand decat arbori din dp[nivel][1] adica formele
            ///posibile pe care le putem repeta => combi cu repetitie
            int x = combiRepet(dp[nivel][1], k);
            backTrack(nivel + 1, grad + k, 1LL * sum * x, ramas - k * nivel, total);
        }
    }
}

signed main()
{
    fin >> n >> mod >> rest;
    dp[1][1] = 1; ///arbore cu un nod unde am radacina frunza
    for(int i=2; i<=n; i++) backTrack(1, 0, 1, i - 1, i);
    fout << dp[n][0];

    return 0;
}