hdu多校第八场 1003 (hdu6659) Acesrc and Good Numbers 数论/打表
题意:
对于某数k,若数字d在1-k中出现次数恰好为k,则称k为好数。
给定d,x,求x以内,对于d而言最大的好数。k范围1e18.
题解:
打表二分即可。
但是,1e18的表是没法打出来的,只能在oeis.org上查出来
#include<iostream> #include<cstdio> #include<cstring> #include<cmath> #include<string> #include<stack> #include<algorithm> #include<map> #include<queue> #include<vector> using namespace std; #define INF 0x3f3f3f3f #define MAXN 100000+50 #define MAXM 30000 #define ll long long #define per(i,n,m) for(int i=n;i>=m;--i) #define rep(i,n,m) for(int i=n;i<=m;++i) #define mod 1000000000 + 7 #define mian main #define mem(a, b) memset(a, b, sizeof a) #ifndef ONLINE_JUDGE #define dbg(x) cout << #x << "=" << x << endl; #else #define dbg(x) #endif inline int read() { int x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = 10 * x + ch - '0'; ch = getchar(); } return x * f; } inline ll readll() { ll x = 0, f = 1; char ch = getchar(); while (ch < '0' || ch > '9') { if (ch == '-') f = -1; ch = getchar(); } while (ch >= '0' && ch <= '9') { x = 10 * x + ch - '0'; ch = getchar(); } return x * f; } ll a1[] = { 0,1,199981,199982,199983,199984,199985,199986,199987,199988,199989,199990,200000,200001,1599981,1599982,1599983,1599984,1599985,1599986,1599987,1599988,1599989,1599990,2600000,2600001,13199998,35000000,35000001,35199981,35199982,35199983,35199984,35199985,35199986,35199987,35199988,35199989,35199990,35200000,35200001,117463825,500000000,500000001,500199981,500199982,500199983,500199984,500199985,500199986,500199987,500199988,500199989,500199990,500200000,500200001,501599981,501599982,501599983,501599984,501599985,501599986,501599987,501599988,501599989,501599990,502600000,502600001,513199998,535000000,535000001,535199981,535199982,535199983,535199984,535199985,535199986,535199987,535199988,535199989,535199990,535200000,535200001,1111111110 }; ll a2[] = { 0,28263827, 35000000, 242463827, 500000000, 528263827, 535000000, 10000000000, 10028263827, 10035000000, 10242463827, 10500000000, 10528263827, 10535000000 }; ll a3[] = { 0, 371599983,371599984,371599985,371599986,371599987,371599988,371599989,371599990,371599991,371599992,500000000,10000000000,10371599983,10371599984,10371599985,10371599986,10371599987,10371599988,10371599989,10371599990,10371599991,10371599992,10500000000,20000000000,20371599983,20371599984,20371599985,20371599986,20371599987,20371599988,20371599989,20371599990,20371599991,20371599992,20500000000}; ll a4[] = { 0, 499999984,499999985,499999986,499999987,499999988,499999989,499999990,499999991,499999992,499999993,500000000,10000000000,10499999984,10499999985,10499999986,10499999987,10499999988,10499999989,10499999990,10499999991,10499999992,10499999993,10500000000,20000000000,20499999984,20499999985,20499999986,20499999987,20499999988,20499999989,20499999990,20499999991,20499999992,20499999993,20500000000,30000000000,30499999984,30499999985,30499999986,30499999987,30499999988,30499999989,30499999990,30499999991,30499999992,30499999993,30500000000}; ll a5[] = { 0, 10000000000, 20000000000, 30000000000, 40000000000 }; ll a6[] = { 0,9500000000,9628399986,9628399987,9628399988,9628399989,9628399990,9628399991,9628399992,9628399993,9628399994,9628399995,10000000000,19500000000,19628399986,19628399987,19628399988,19628399989,19628399990,19628399991,19628399992,19628399993,19628399994,19628399995,20000000000,29500000000,29628399986,29628399987,29628399988,29628399989,29628399990,29628399991,29628399992,29628399993,29628399994,29628399995,30000000000,39500000000,39628399986,39628399987,39628399988,39628399989,39628399990,39628399991,39628399992,39628399993,39628399994,39628399995,40000000000,49500000000,49628399986,49628399987,49628399988,49628399989,49628399990,49628399991,49628399992,49628399993,49628399994,49628399995,50000000000,59500000000,59628399986,59628399987,59628399988,59628399989,59628399990,59628399991,59628399992,59628399993,59628399994,59628399995 }; ll a7[] = { 0,9465000000,9471736170,9500000000,9757536170,9965000000,9971736170,10000000000,19465000000,19471736170,19500000000,19757536170,19965000000,19971736170,20000000000,29465000000,29471736170,29500000000,29757536170,29965000000,29971736170,30000000000,39465000000,39471736170,39500000000,39757536170,39965000000,39971736170,40000000000,49465000000,49471736170,49500000000,49757536170,49965000000,49971736170,50000000000,59465000000,59471736170,59500000000,59757536170,59965000000,59971736170,60000000000,69465000000,69471736170,69500000000,69757536170,69965000000,69971736170 }; ll a8[] = { 0,9465000000,9486799989,9486799990,9486799991,9486799992,9486799993,9486799994,9486799995,9486799996,9486799997,9497400000,9498399989,9498399990,9498399991,9498399992,9498399993,9498399994,9498399995,9498399996,9498399997,9500000000,9882536171,9965000000,9986799989,9986799990,9986799991,9986799992,9986799993,9986799994,9986799995,9986799996,9986799997,9997400000,9998399989,9998399990,9998399991,9998399992,9998399993,9998399994,9998399995,9998399996,9998399997,10000000000,19465000000,19486799989,19486799990,19486799991,19486799992,19486799993,19486799994,19486799995,19486799996,19486799997,19497400000,19498399989,19498399990,19498399991,19498399992,19498399993,19498399994,19498399995,19498399996,19498399997,19500000000,19882536171,19965000000,19986799989,19986799990,19986799991,19986799992,19986799993,19986799994,19986799995,19986799996,19986799997,19997400000,19998399989,19998399990,19998399991,19998399992,19998399993,19998399994,19998399995,19998399996,19998399997,20000000000,29465000000,29486799989,29486799990,29486799991,29486799992,29486799993,29486799994,29486799995,29486799996,29486799997,29497400000,29498399989,29498399990,29498399991,29498399992,29498399993,29498399994,29498399995,29498399996,29498399997,29500000000,29882536171,29965000000,29986799989,29986799990,29986799991,29986799992,29986799993,29986799994,29986799995,29986799996,29986799997,29997400000,29998399989,29998399990,29998399991,29998399992,29998399993,29998399994,29998399995,29998399996,29998399997,30000000000,39465000000,39486799989,39486799990,39486799991,39486799992,39486799993,39486799994,39486799995,39486799996,39486799997,39497400000,39498399989,39498399990,39498399991,39498399992,39498399993,39498399994,39498399995,39498399996,39498399997,39500000000,39882536171,39965000000,39986799989,39986799990,39986799991,39986799992,39986799993,39986799994,39986799995,39986799996,39986799997,39997400000,39998399989,39998399990,39998399991,39998399992,39998399993,39998399994,39998399995,39998399996,39998399997,40000000000,49465000000,49486799989,49486799990,49486799991,49486799992,49486799993,49486799994,49486799995,49486799996,49486799997,49497400000,49498399989,49498399990,49498399991,49498399992,49498399993,49498399994,49498399995,49498399996,49498399997,49500000000,49882536171,49965000000,49986799989,49986799990,49986799991,49986799992,49986799993,49986799994,49986799995,49986799996,49986799997,49997400000,49998399989,49998399990,49998399991,49998399992,49998399993,49998399994,49998399995,49998399996,49998399997,50000000000,59465000000,59486799989,59486799990,59486799991,59486799992,59486799993,59486799994,59486799995,59486799996,59486799997,59497400000,59498399989,59498399990,59498399991,59498399992,59498399993,59498399994,59498399995,59498399996,59498399997,59500000000,59882536171,59965000000,59986799989,59986799990,59986799991,59986799992,59986799993,59986799994,59986799995,59986799996,59986799997,59997400000,59998399989,59998399990,59998399991,59998399992,59998399993,59998399994,59998399995,59998399996,59998399997,60000000000,69465000000,69486799989,69486799990,69486799991,69486799992,69486799993,69486799994,69486799995,69486799996,69486799997,69497400000,69498399989,69498399990,69498399991,69498399992,69498399993,69498399994,69498399995,69498399996,69498399997,69500000000,69882536171,69965000000,69986799989,69986799990,69986799991,69986799992,69986799993,69986799994,69986799995,69986799996,69986799997,69997400000,69998399989,69998399990,69998399991,69998399992,69998399993,69998399994,69998399995,69998399996,69998399997,70000000000,79465000000,79486799989,79486799990,79486799991,79486799992,79486799993,79486799994,79486799995,79486799996,79486799997,79497400000,79498399989,79498399990,79498399991,79498399992,79498399993,79498399994,79498399995,79498399996,79498399997,79500000000,79882536171,79965000000,79986799989,79986799990,79986799991,79986799992,79986799993,79986799994,79986799995,79986799996,79986799997,79997400000,79998399989,79998399990,79998399991,79998399992,79998399993,79998399994,79998399995,79998399996,79998399997 }; ll a9[] = { 0, 10000000000, 20000000000, 30000000000, 40000000000, 50000000000, 60000000000, 70000000000, 80000000000 }; int main() { int _ = read(); int cnt1 = 84; int cnt2 = 14, cnt3 = 36, cnt4 = 48, cnt5 = 5, cnt6 = 72, cnt7 = 49, cnt8 =344, cnt9 = 9; while (_--) { int n = read(); ll x = readll(); if (n == 1) { ll pos; for (int i = 0; i < cnt1; ++i) { if (a1[i] <= x) pos = a1[i]; } printf("%lld\n", pos); } else if (n == 2) { ll pos; for (int i = 0; i < cnt2; ++i) { if (a2[i] <= x) pos = a2[i]; } printf("%lld\n", pos); } else if (n == 3) { ll pos; for (int i = 0; i < cnt3; ++i) { if (a3[i] <= x) pos = a3[i]; } printf("%lld\n", pos); } else if (n == 4) { ll pos; for (int i = 0; i < cnt4; ++i) { if (a4[i] <= x) pos = a4[i]; } printf("%lld\n", pos); } else if (n == 5) { ll pos; for (int i = 0; i < cnt5; ++i) { if (a5[i] <= x) pos = a5[i]; } printf("%lld\n", pos); } else if (n == 6) { ll pos; for (int i = 0; i < cnt6; ++i) { if (a6[i] <= x) pos = a6[i]; } printf("%lld\n", pos); } else if (n == 7) { ll pos; for (int i = 0; i < cnt7; ++i) { if (a7[i] <= x) pos = a7[i]; } printf("%lld\n", pos); } else if (n == 8) { ll pos; for (int i = 0; i < cnt8; ++i) { if (a8[i] <= x) pos = a8[i]; } printf("%lld\n", pos); } else if (n == 9) { ll pos; for (int i = 0; i < cnt9; ++i) { if (a9[i] <= x) pos = a9[i]; } printf("%lld\n", pos); } } }
下面补充关于此题的一个定理证明。
好数不会超过1e11
证明:记f(d,k)为1-k中数字d出现的次数,记g(d,k)=f(d,k)-k
由于对于d=1-9 已经有g(d,1e11-1)=1e10+1
因此对于任意k>1e11 有g(d,k+1e10)-g(d,k)>=1e10(考虑数的后缀是如何组成的)
通俗来讲,在1e11以后,数字d已经比数k多太多了,d再多也追不上了
可以考虑分块,维护数字的后缀信息,以加速打表。