提高1训练D求调(WA on test18

题目

思路就是做两次二分,然后确定所在的数字,样例都没问题

#include<iostream>
#include<algorithm>
#include<map>
#include<cstring> 
#include<iomanip>
#include<math.h>
#include<vector>
#define MAX 1e17
#define int long long
using namespace std;
int sum2[114];
vector<int> sum;
int p10[30],k;
int  check(int bit,int n){//位数和第几个数 
	int a_1=sum2[bit-1]+bit,S;
    S=n*a_1+n*(n-1)/2*bit;
	return  S;  
} 
signed main(){
	p10[0]=1;
	for(int i=1;i<=21;i++) p10[i]=p10[i-1]*10;
	sum.push_back(0);
	for(int i=1;i<=17;i++){//预处理 
		int n=p10[i]-p10[i-1];
		sum2[i]=n*i+sum2[i-1];
		if(i<=9) sum.push_back(n*(sum2[i-1]+i)+n*(n-1)/2*i+sum[i-1]);
	}
	int t;
	cin>>t;
	while(t--){
		cin>>k;
		int pos=lower_bound(sum.begin(),sum.end(),k)-sum.begin();
		k-=sum[pos-1];
		int l=1,r=p10[pos]-p10[pos-1];
		while(l<r){//二分以哪个数结尾 
			int mid=(l+r)>>1;
			if(check(pos,mid)<k) l=mid+1;
			else r=mid; 
		}
		k-=check(pos,l-1);
		int i=1;
		while(k-sum2[i]>0) i++;
		k-=sum2[i-1];
		int tail=p10[i-1]+k/i-1,mod=k%i,dig;//确定所在的数字 
		if(!mod) mod=i;mod=i+1-mod;
		for(int j=1;j<=mod;j++){
			dig=tail%10;
			tail/=10;
		}
		cout<<dig<<endl;
	}
	return 0;
}