Codeforces 1216E2 枚举位数+二分

两个二分 枚举位数

#include 
#define MOD 1000000007
using namespace std;
typedef long long ll;
ll ten[15];
ll check1(ll x) {
        ll ans = 0;
        ll l, r;
        for (ll i = 1; i <= 9; i++) {
                l = ten[i], r = ten[i + 1] - 1;
                if (r < x) {
                        ans += i * (2 * x - l - r) * (r - l + 1) / 2;
                } else {
                        ans += i * (x - l) * (x - l + 1) / 2;
                        break;
                }
        }
        return ans;
}
ll check2(ll x) {
        ll ans = 0;
        ll l, r;
        for (ll i = 1; i <= 9; i++) {
                l = ten[i], r = ten[i + 1] - 1;
                if (r <= x) {
                        ans += i * (r - l + 1);
                } else {
                        ans += i * (x - l + 1);
                        break;
                }
        }
        return ans;
}
int main () {
        ten[1] = 1;
        for (int i = 2; i <= 10; i++) {
                ten[i] = ten[i - 1] * 10LL;
        }
        int Q;
        scanf("%d", &Q);
        while (Q--) {
                ll n;
                scanf("%lld", &n);
                ll l = 0, r = 1e9, mid;
                while (l < r - 1) {
                        mid = (l + r) >> 1;
                        if (check1(mid) < n) {
                                l = mid;
                        } else {
                                r = mid;
                        }
                }
                n -= check1(r - 1);
                if (n == 0) {
                        printf("%d\n", (r - 1) % 10);
                        continue;
                }
                l = 0;
                r = 1e9;
                while (l < r - 1) {
                        mid = (l + r) >> 1;
                        if (check2(mid) < n) {
                                l = mid;
                        } else {
                                r = mid;
                        }
                }
                n -= check2(r - 1);
                int len = 0;
                ll xxx = r, xxxx = r;
                while (xxx > 0) {
                        xxx /= 10LL;
                        len++;
                }
                len -= n;
                if (len < 0) {
                        continue;
                }
                while (len--) {
                        xxxx /= 10;
                }
                printf("%lld\n", xxxx % 10);
        }
}

 

转载于:https://www.cnblogs.com/Aragaki/p/11580349.html

你可能感兴趣的:(Codeforces 1216E2 枚举位数+二分)