QOJ.ac
QOJ
ID | 题目 | 提交者 | 结果 | 用时 | 内存 | 语言 | 文件大小 | 提交时间 | 测评时间 |
---|---|---|---|---|---|---|---|---|---|
#184982 | #4904. 圆滚滚的算术占卜 | hos_lyric# | 5 | 171ms | 194980kb | C++14 | 9.1kb | 2023-09-21 15:19:26 | 2024-07-04 02:06:14 |
Judging History
answer
#include <cassert>
#include <cmath>
#include <cstdint>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <bitset>
#include <complex>
#include <deque>
#include <functional>
#include <iostream>
#include <limits>
#include <map>
#include <numeric>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <unordered_map>
#include <unordered_set>
#include <utility>
#include <vector>
using namespace std;
using Int = long long;
template <class T1, class T2> ostream &operator<<(ostream &os, const pair<T1, T2> &a) { return os << "(" << a.first << ", " << a.second << ")"; };
template <class T> ostream &operator<<(ostream &os, const vector<T> &as) { const int sz = as.size(); os << "["; for (int i = 0; i < sz; ++i) { if (i >= 256) { os << ", ..."; break; } if (i > 0) { os << ", "; } os << as[i]; } return os << "]"; }
template <class T> void pv(T a, T b) { for (T i = a; i != b; ++i) cerr << *i << " "; cerr << endl; }
template <class T> bool chmin(T &t, const T &f) { if (t > f) { t = f; return true; } return false; }
template <class T> bool chmax(T &t, const T &f) { if (t < f) { t = f; return true; } return false; }
#define COLOR(s) ("\x1b[" s "m")
////////////////////////////////////////////////////////////////////////////////
template <unsigned M_> struct ModInt {
static constexpr unsigned M = M_;
unsigned x;
constexpr ModInt() : x(0U) {}
constexpr ModInt(unsigned x_) : x(x_ % M) {}
constexpr ModInt(unsigned long long x_) : x(x_ % M) {}
constexpr ModInt(int x_) : x(((x_ %= static_cast<int>(M)) < 0) ? (x_ + static_cast<int>(M)) : x_) {}
constexpr ModInt(long long x_) : x(((x_ %= static_cast<long long>(M)) < 0) ? (x_ + static_cast<long long>(M)) : x_) {}
ModInt &operator+=(const ModInt &a) { x = ((x += a.x) >= M) ? (x - M) : x; return *this; }
ModInt &operator-=(const ModInt &a) { x = ((x -= a.x) >= M) ? (x + M) : x; return *this; }
ModInt &operator*=(const ModInt &a) { x = (static_cast<unsigned long long>(x) * a.x) % M; return *this; }
ModInt &operator/=(const ModInt &a) { return (*this *= a.inv()); }
ModInt pow(long long e) const {
if (e < 0) return inv().pow(-e);
ModInt a = *this, b = 1U; for (; e; e >>= 1) { if (e & 1) b *= a; a *= a; } return b;
}
ModInt inv() const {
unsigned a = M, b = x; int y = 0, z = 1;
for (; b; ) { const unsigned q = a / b; const unsigned c = a - q * b; a = b; b = c; const int w = y - static_cast<int>(q) * z; y = z; z = w; }
assert(a == 1U); return ModInt(y);
}
ModInt operator+() const { return *this; }
ModInt operator-() const { ModInt a; a.x = x ? (M - x) : 0U; return a; }
ModInt operator+(const ModInt &a) const { return (ModInt(*this) += a); }
ModInt operator-(const ModInt &a) const { return (ModInt(*this) -= a); }
ModInt operator*(const ModInt &a) const { return (ModInt(*this) *= a); }
ModInt operator/(const ModInt &a) const { return (ModInt(*this) /= a); }
template <class T> friend ModInt operator+(T a, const ModInt &b) { return (ModInt(a) += b); }
template <class T> friend ModInt operator-(T a, const ModInt &b) { return (ModInt(a) -= b); }
template <class T> friend ModInt operator*(T a, const ModInt &b) { return (ModInt(a) *= b); }
template <class T> friend ModInt operator/(T a, const ModInt &b) { return (ModInt(a) /= b); }
explicit operator bool() const { return x; }
bool operator==(const ModInt &a) const { return (x == a.x); }
bool operator!=(const ModInt &a) const { return (x != a.x); }
friend std::ostream &operator<<(std::ostream &os, const ModInt &a) { return os << a.x; }
};
////////////////////////////////////////////////////////////////////////////////
constexpr unsigned MO = 998244353;
using Mint = ModInt<MO>;
constexpr int E = 18;
Int ten[E + 1];
constexpr int LIM_BRUTE = 260'000;
pair<Mint, Mint> brt[LIM_BRUTE + 1];
Mint brtSum[LIM_BRUTE + 1];
/*
start: len(hi) = f, S(hi) = a, lo = 10^e - b
score: x -> p x + q hi + r
goal: --hi, lo = 10^e - c
*/
struct Result {
Mint p, q, r;
int c;
void mul(Mint val) {
p *= val;
q *= val;
r *= val;
}
friend ostream &operator<<(ostream &os, const Result &r) {
return os << "(" << r.p << "," << r.q << "," << r.r << "; " << r.c << ")";
}
};
Result small[E][9 * E + 1][1000];
Result dp[E + 1][E][9 * E + 1][9 * E + 1];
// 0 -> []
vector<int> toDigits(Int s) {
vector<int> digits;
for (; s; s /= 10) {
digits.push_back(s % 10);
}
return digits;
}
Mint solve(Int s) {
Mint score = 0;
if (s == ten[E]) {
score = s;
--s;
}
if (s < ten[3]) {
const Result &res = small[0][0][s];
score *= res.p;
score += res.r;
assert(!res.c);
return score;
}
{
const auto digits = toDigits(s);
const int len = digits.size();
assert(3 < len); assert(len <= E);
int a = 0;
for (int e = 3; e < len; ++e) a += digits[e];
const Result &res = small[len - 3][a][s % ten[3]];
score *= res.p;
score += res.q * (s / ten[3]);
score += res.r;
assert(res.c);
s = s / ten[3] * ten[3] - res.c;
}
if (s < ten[3]) {
const Result &res = small[0][0][s];
score *= res.p;
score += res.r;
return score;
}
{
auto digits = toDigits(s);
const int len = digits.size();
assert(3 < len); assert(len <= E);
int a = 0;
for (int e = 3; e < len; ++e) a += digits[e];
for (int e = 3; e < len; ++e) {
a -= digits[e];
for (int &m = digits[e]; m >= 0; ) {
// cerr<<"e = "<<e<<"; s = "<<s<<", digits = "<<digits<<", a = "<<a<<", m = "<<m<<endl;
const int c = ten[e] - s % ten[e];
if (e == len - 1 && m == 0) {
assert(a == 0);
const Result &res = dp[e][0][0][c];
// cerr<<" "<<e<<" "<<0<<" "<<0<<" "<<c<<": "<<res<<endl;
score *= res.p;
score += res.r;
assert(!res.c);
return score;
} else {
const Result &res = dp[e][len - e][a + m][c];
// cerr<<" "<<e<<" "<<len-e<<" "<<a+m<<" "<<c<<": "<<res<<endl;
score *= res.p;
score += res.q * (s / ten[e]);
score += res.r;
assert(res.c);
s += c;
s -= ten[e];
s -= res.c;
--m;
}
}
--a;
--digits[e + 1];
}
}
assert(false);
}
int main() {
ten[0] = 1;
for (int e = 1; e <= E; ++e) ten[e] = ten[e - 1] * 10;
brt[0] = make_pair(1, 0);
for (int s = 1; s <= LIM_BRUTE; ++s) {
int len = 0, d = 0;
for (int ss = s; ss; ss /= 10) {
++len;
d += ss % 10;
}
brt[s] = make_pair(ten[len] * brt[s - d].first, s * brt[s - d].first + brt[s - d].second);
}
cerr<<"brt[32] = "<<brt[32]<<endl;
for (int s = 1; s <= LIM_BRUTE; ++s) {
brtSum[s] = brtSum[s - 1] + brt[s].second;
}
{
for (int f = 0; f <= E - 3; ++f) for (int a = f ? 1 : 0; a <= 9 * f; ++a) {
for (int s = 0; s < ten[3]; ++s) {
Result &ret = small[f][a][s];
ret.p = 1;
if (f || s) {
ret.mul(ten[f]);
ret.q += 1;
ret.mul(ten[f ? 3 : (int)to_string(s).size()]);
ret.r += s;
int d = a;
for (int g = 0; g < 3; ++g) d += s / ten[g] % 10;
assert(d > 0);
if (s < d) {
ret.c = d - s;
} else {
const Result &res = small[f][a][s - d];
ret.mul(res.p);
ret.q += res.q;
ret.r += res.r;
ret.c = res.c;
}
}
}
}
}
cerr<<"small[0][0][32] = "<<small[0][0][32]<<endl;
cerr<<"small[0][0][1] = "<<small[0][0][1]<<endl;
{
for (int f = 0; f <= E - 3; ++f) for (int a = f ? 1 : 0; a <= 9 * f; ++a) {
for (int b = 1; b <= 9 * E; ++b) {
dp[3][f][a][b] = small[f][a][ten[3] - b];
}
}
}
for (int e = 4; e <= E; ++e) {
for (int f = 0; f <= E - e; ++f) for (int a = f ? 1 : 0; a <= 9 * f; ++a) {
for (int b = 1; b <= 9 * E; ++b) {
Result &ret = dp[e][f][a][b];
ret.p = 1;
ret.c = b;
for (int m = 10; --m >= 0; ) {
const Result &res = dp[e - 1][(f || m) ? (f + 1) : 0][a + m][ret.c];
// if(e==4&&f==0&&a==0&&b==1)cerr<<"HELP"<<__LINE__<<" "<<e-1<<" "<<((f || m) ? (f + 1) : 0)<<" "<<a+m<<" "<<ret.c<<": "<<res<<endl;
ret.mul(res.p);
ret.q += res.q * 10;
ret.r += res.q * m;
ret.r += res.r;
ret.c = res.c;
}
}
}
}
for (int numCases; ~scanf("%d", &numCases); ) { for (int caseId = 1; caseId <= numCases; ++caseId) {
Int L, R;
scanf("%lld%lld", &L, &R);
Mint ans = 0;
if (R <= LIM_BRUTE) {
ans = brtSum[R] - brtSum[L - 1];
} else {
for (Int s = L; s <= R; ++s) {
const Mint slv = solve(s);
if (s <= LIM_BRUTE) {
if (brt[s].second != slv) {
cerr << s << ": " << brt[s] << " " << slv << endl;
}
assert(brt[s].second == slv);
}
ans += slv;
}
}
printf("%u\n", ans.x);
}
#ifndef LOCAL
break;
#endif
}
return 0;
}
详细
Subtask #1:
score: 5
Accepted
Test #1:
score: 5
Accepted
time: 163ms
memory: 194964kb
input:
10 9653 62002 91160 95589 4602 60141 54240 79592 69170 95623 46733 68190 25361 84435 23506 99583 62553 65996 22099 81703
output:
103592019 222392703 236171250 287406393 478554731 117904238 522507555 617451444 277292124 553293749
result:
ok 10 numbers
Test #2:
score: 0
Accepted
time: 171ms
memory: 194932kb
input:
500 174 85257 53439 99201 25556 99022 59548 92909 61936 77935 35851 62882 67138 71164 42431 65794 15439 89519 5723 18456 23983 25568 22597 68086 23328 93569 9292 67330 18318 88994 84792 90364 13981 83990 21502 61839 4123 63779 498 68986 34607 65882 11483 67457 22349 94822 24528 42149 14737 16569 643...
output:
588662657 274087272 994096268 769521372 234323706 928183056 662030711 217503980 734291561 395959901 588662067 240307614 780366739 980869834 300892674 79160805 615092140 4805327 818222180 368256926 937099344 664493054 822178346 136725071 480882109 856568785 118890530 234462958 831460844 238212390 186...
result:
ok 500 numbers
Test #3:
score: 0
Accepted
time: 171ms
memory: 194624kb
input:
500 76018 100000 93967 99999 32658 99998 88768 99997 53643 99996 6743 99995 66089 99994 40514 99993 24204 99992 30127 99991 55799 99990 35717 99989 98626 99988 32251 99987 75425 99986 26188 99985 88810 99984 56572 99983 78303 99982 94046 99981 76956 99980 55343 99979 67855 99978 48154 99977 88369 99...
output:
966615136 849139888 6267017 916820590 521834522 922204325 838533981 670560015 961311832 212078764 499503191 129196363 987715820 900604607 573266380 598854085 678826229 560106902 885695117 182655480 986707578 531178447 47748447 914611030 683369442 290251694 778653294 214408897 337506302 29387069 8568...
result:
ok 500 numbers
Subtask #2:
score: 0
Wrong Answer
Test #4:
score: 10
Accepted
time: 169ms
memory: 194668kb
input:
5 14151615 14151615 50959220 50959220 177962208 177962208 173507309 173507309 608527742 608527742
output:
574888399 728657674 419976531 502012045 456375259
result:
ok 5 number(s): "574888399 728657674 419976531 502012045 456375259"
Test #5:
score: 0
Accepted
time: 161ms
memory: 194980kb
input:
5 441384319 441384319 606726578 606726578 100872719 100872719 290542038 290542038 290435521 290435521
output:
304014472 49910017 871510667 927387471 830052470
result:
ok 5 number(s): "304014472 49910017 871510667 927387471 830052470"
Test #6:
score: -10
Wrong Answer
time: 104ms
memory: 194684kb
input:
5 686934834 686934834 217972715 217972715 91760217 91760217 478910665 478910665 871116356 871116356
output:
result:
wrong output format Output file not found: ""
Subtask #3:
score: 0
Skipped
Dependency #2:
0%
Subtask #4:
score: 0
Skipped
Dependency #3:
0%
Subtask #5:
score: 0
Skipped
Dependency #1:
100%
Accepted
Dependency #2:
0%
Subtask #6:
score: 0
Skipped
Dependency #5:
0%