牛客挑战赛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; }
一步一步,永不停息