TCO 2020 R4 Med - SORTINVERSIONS
解法
問題文を言い換えると、 かつのようなペアが何個あるか数え上げる問題になる。
桁数が同じ数字を考えると、であるので、桁数が異なる場合だけ考えればいい
とすると、桁数がと ()のような上記の条件を満たす整数の組み合わせは簡単な算数で求められる。
桁数がと ()となる整数の組み合わせは少しやっかいで、桁の数字はを超えてはいけないことに注意しないといけないので桁DPをするといい。
実装例
#include <iostream> #include <string> #include <sstream> #include <stack> #include <algorithm> #include <cmath> #include <queue> #include <bitset> #include <iomanip> #include <limits> #include <chrono> #include <random> #include <array> #include <unordered_map> #include <functional> #include <complex> #include <numeric> #include <cctype> #include <map> #include <set> #include <cstdlib> #include <bitset> #include <tuple> #include <assert.h> #include <deque> #include <utility> #include <fstream> using namespace std; typedef long long ll; template<class T> inline bool chmax(T& a, T b) { if (a < b) { a = b; return 1; } return 0; } template<class T> inline bool chmin(T& a, T b) { if (a > b) { a = b; return 1; } return 0; } template<typename T> T gcd(T a, T b) { a = abs(a), b = abs(b); while (b > 0) { tie(a, b) = make_pair(b, a % b); } return a; } //mt19937 rnd(chrono::steady_clock::now().time_since_epoch().count()); constexpr long long INF = 1LL << 60; constexpr int inf = 1000000007; constexpr long long mod = 1000000007LL; //constexpr long long mod = 998244353LL; ll f(ll x) { return x * (x + 1) / 2; } class SortInversions { public: long long count(int _N) { ll ten[19] = {}; ten[0] = 1; for (ll i = 1; i < 19; i++) ten[i] = ten[i - 1] * 10; ll n = _N; string t = to_string(n); int sz = t.size(); ll res = 0; for (int s = 1; s < sz; s++) { for (int l = s + 1; l < sz; l++) { for (int k = 1; k <= s; k++) { if (k == 1) { res += f(8) * ten[s + l - 2]; } else { res += f(9) * 9 * ten[k - 2] * ten[s - k] * ten[l - k]; } } } } for (int s = 1; s < sz; s++) { vector<vector<vector<ll>>> dp(sz + 1, vector<vector<ll>>(2, vector<ll>(2))); dp[0][0][0] = 1; for (int i = 0; i < sz; i++) { ll mx = 10; { for (int j = 0; j < t[i] - '0'; j++) { if (i == 0 and j == 0) continue; if (i + 1 <= s) dp[i + 1][1][1] += dp[i][0][0] * (mx - j - 1); dp[i + 1][1][0] += dp[i][0][0]; if (i + 1 <= s) dp[i + 1][1][1] += dp[i][0][1] * mx; else dp[i + 1][1][1] += dp[i][0][1]; } dp[i + 1][0][0] += dp[i][0][0]; if (i + 1 <= s) dp[i + 1][0][1] += dp[i][0][0] * (mx - (t[i] - '0') - 1); if (i + 1 <= s)dp[i + 1][0][1] += dp[i][0][1] * mx; else dp[i + 1][0][1] += dp[i][0][1]; } dp[i + 1][1][0] += dp[i][1][0] * mx; if(i + 1 <= s) dp[i + 1][1][1] += dp[i][1][0] * f(mx - 1); if (i + 1 <= s) dp[i + 1][1][1] += dp[i][1][1] * mx * mx; else dp[i + 1][1][1] += dp[i][1][1] * mx; } res += dp[sz][0][1] + dp[sz][1][1]; } return res; } };