牛客挑战赛40 A-小V和方程 (思维、数学、整数拆分、dp)

时间:2020-05-16
本文章向大家介绍牛客挑战赛40 A-小V和方程 (思维、数学、整数拆分、dp),主要包括牛客挑战赛40 A-小V和方程 (思维、数学、整数拆分、dp)使用实例、应用技巧、基本知识点总结和需要注意事项,具有一定的参考价值,需要的朋友可以参考一下。

题目:传送门

题意

 思路

将 m 写成 a * sqrt(b) 的形式,每个 xi 必然是 ui * sqrt(b) 的形式,且 u1 + u2 + .... + un = a;

那么问题就转化为了,求 u1 + u2 + ... + un = a 有多少本质不同的解,这个问题是经典的整数拆分问题,o(n^2) dp 即可

#include <bits/stdc++.h>
#define LL long long
#define ULL unsigned long long
#define UI unsigned int
#define mem(i, j) memset(i, j, sizeof(i))
#define rep(i, j, k) for(int i = j; i <= k; i++)
#define dep(i, j, k) for(int i = k; i >= j; i--)
#define pb push_back
#define make make_pair
#define INF 0x3f3f3f3f3f3f3f3f
#define inf LLONG_MAX
#define PI acos(-1)
#define fir first
#define sec second
#define lb(x) ((x)h & (-(x)))
#define dbg(x) cout<<#x<<" = "<<x<<endl;
using namespace std;

const int N = 1e6 + 5;
const LL mod = 998244353;

LL dp[N];

void solve() {

    int n, m;

    scanf("%d %d", &n, &m);

    int tmp = 1;

    for(int i = 2; i * i <= m; i++) {

        while(m % (i * i) == 0) {

            m /= (i * i);

            tmp *= i;

        }

    }

    dp[0] = 1;

    rep(j, 1, n) rep(i, j, tmp) {

        dp[i] = (dp[i] + dp[i - j]) % mod;

    }

    printf("%lld\n", dp[tmp]);

}

int main() {

//    int _; scanf("%d", &_);
//    while(_--) solve();

    solve();

    return 0;
}

原文地址:https://www.cnblogs.com/Willems/p/12898861.html