#include #include #include #include #include const char * infile = "longnumber.inp"; const char *outfile = "longnumber.out"; int arr[2][201]; long long pos; int ans; int printll(long long c, int ss[]) { int i = 0; do { ss[i++] = c % 10LL; c /= 10LL; } while (c); return i; /* while (i>=0) { printf("%d", ss[i]); i--; }*/ } void printqq(long long c) { int ss[100]; int i = 0; do { ss[i++] = c % 10LL; c /= 10LL; } while (c); i--; while (i>=0) { printf("%d", ss[i]); i--; } // printf("\n"); } int mylog10(long long x) { int c = 0; while (x>=10LL) { x/=10LL; c++; } return c; } int exp10(int x) { int p = 1; for (int i = 0; i < x; i++) p*=10; return p; } long long countdigs(int x) { if (x < 10) return (x-1); int p = 1; int c = 1; long long all = 0LL; while (p *10 <= x) { all += (long long) ((p*10)-(p)) * c; p *= 10; c++; } all += (x-p)*c; return all; } int step = 10000; long long countdigs1(int x) { long long all=0; for (int i = 1; i < x;) { step = 10000; int f1, f2, n; //do { step /= 2; step >?= 1; n = i + step; n i + 100); if (f1 != f2 || n >= x) { for (int j = i; j <= n; j++) { long long gog = j; gog *= gog; all += mylog10(gog) + 1; } } else { all += (n-i+1)*f1; } i = n + 1; //all += mylog10(q)+1; } return all; } void solve(void) { int x[1000]; long long gpos = 0; for (int n = 1; ; n++) { int r = printll(n, x); for (int i = r-1; i >= 0; i--) { if (gpos>= pos-100LL && gpos <= pos+100LL) { arr[0][gpos-pos+100LL] = x[i]; } gpos++; } if (gpos > pos + 100LL) { // printf("cycle 1 broken at %d\n", n); break; } } gpos = 0; for (int n = 1; ; n ++) { long long xx = n; xx *= xx; int r = printll(xx, x); for (int i = r-1; i >= 0; i--) { if (gpos>= pos-100LL && gpos <= pos+100LL) { arr[1][gpos-pos+100LL] = x[i]; } gpos++; } if (gpos > pos + 100LL) { // printf("cycle 1 broken at %d\n", n); break; } } int carry = 0; for (int i = 200; i >= 0; i--) { arr[1][i] += arr[0][i] + carry; carry = arr[1][i] / 10; arr[1][i] %= 10; } ans = arr[1][100]; } int b1n(int l, int r, long long (*fun) (int), long long target) { long long lt, rt; lt = fun(l); rt = fun(r); while (r-l>3) { int m = (int) (l + (r-l)*((double)(target-lt)/(rt-lt))); if (m==l) m++; if (m==r) m--; long long mt = fun(m); if (mt < target) { l = m; lt = mt; } else { r = m; rt = mt; } } return (l+r)/2; } void dowork(int *arr, long long (*fun) (int), int right, bool sqr = false) { int x[1000]; int l = b1n(0, right, fun, pos-120); int ro = b1n(0, right, fun, pos+120); // printf("will scan from %d to %d;", l, ro); long long gpos = fun(l); // printf("gpos = "); printqq(gpos);printf("\n"); for (int n = l; ; n++) { long long pp = n; if (sqr) pp*=pp; int r = printll(pp, x); for (int i = r-1; i >= 0; i--) { if (gpos>= pos-100LL && gpos <= pos+100LL) { arr[gpos-pos+100LL] = x[i]; } gpos++; } if (gpos > pos + 100LL) { // printf("cycle 1 broken at %d\n", n); break; } } } void solve2(void) { int x[1000]; dowork(arr[0], countdigs, 300000000); dowork(arr[1], countdigs1, 150000000, true); int carry = 0; for (int i = 200; i >= 0; i--) { arr[1][i] += arr[0][i] + carry; carry = arr[1][i] / 10; arr[1][i] %= 10; } ans = arr[1][100]; } int main(void) { unsigned ppos; FILE *f = fopen(infile, "rt"); // FILE *f = stdin; FILE *out = fopen(outfile, "wt"); // FILE *out = stdout; while (1 == fscanf(f, "%ud", &ppos)) { long t = clock(); // printf("pos = %u\n", ppos); pos = ppos; pos--; if (pos < 10000) solve(); else solve2(); fprintf(out, "%d\n", ans); // printf(" (%d secs)\n", clock()-t); } // system("pause"); fclose(f); fclose(out); /* int x; while (1) { scanf("%d", &x); printf("to num x there are "); printqq(countdigs(x));printf(" digits\n"); printf("to num x there are "); printqq(countdigs1(x));printf(" digits1\n"); }*/ }