CF#587Div3

# 587Div3

E1

The meaning of problems

Like this number of columns. 3 2. 4 5,678,910,111,213,141,516 ......
request of \ (n-\) term
\ (n <10 ^ 9 \ )

solution

Grouped by number, a first group is the second group 12 is the third group 123 is a group of n 1 2 3 4 5 ... n
violence found in which group
the number of pre-treatment and then the 1-n the first few are 0-9 in which the number of
violence within the group, find answers

Code 100

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cmath> 
using namespace std;
int Q,res,cnt,maxx;
int num[500005],p[500005],now[500005];
struct node{
    int id,k,ans;
}q[505];
bool cmp(node a,node b){
    return a.k <b.k ;
}
bool cmp2(node a,node b){
    return a.id <b.id ;
}
int main()
{
    scanf("%d",&Q);
    for(int i=1;i<=Q;i++){
        scanf("%d",&q[i].k);
        q[i].id =i;
        maxx=max(maxx,q[i].k);
    }
    sort(q+1,q+Q+1,cmp);
    maxx=sqrt(2*maxx)+1;
    for(int i=1;i<=maxx;i++){
        int x=i,cnt=0;
        while(x){
            now[++cnt]=x%10;
            x/=10;
        }
        num[i]=num[i-1]+cnt;
        while(cnt){
            ++res;
            p[res]=now[cnt];
            --cnt;
        }
    }
    int from=1,last=0;
    for(int i=1;i<=Q;i++){
        while(from<=maxx){
            if(num[from]+last<q[i].k){
                last+=num[from++];
                continue;
            }
            
            q[i].k -=last;
            q[i].ans =p[q[i].k];
            break;
        }
    }
    sort(q+1,q+Q+1,cmp2);
    for(int i=1;i<=Q;i++) printf("%d ",q[i].ans );
    return 0;
}

E2

n<10^18

  • First-half in which group, then half of the position at which this group
  • consider
  • 1
  • 1 2
  • 1 2 3
  • 1 2 3 4
  • 1 2 3 4 5
  • 1 2 3 4 5 ....9
  • 1 2 3 4 5 6 ... 10
  • Set the number of bits is \ (n \)
  • The triangle above the front row and the number of bits x, can be classified by the number of bits, number of bits in a same class.
  • This allows the same requirements as in FIG.
  • enter image description here

enter image description here

Each triangle digital and are \ (J * (. 9 * I) * (. 9 * I +. 1) / 2 \) , the rectangular area under each triangle \ (j * 9 * i * (x-10 * +. 1 I) \)
\ (J \) refers to the number of bits of the class numbers, \ (I-J = 10. 1 ^ {} \)
triangle and is equivalent to a count number of the arithmetic sequence summing

  • Note that boundary 10 is considered as the second group

  • Then the two separated groups, then the position of two points in the group
  • Look below to find the law

1 2 3 4 5 6 7 8 9
\(1*9*10^0=1*(9-1+1)\)

10 11 12 13 14 15 16 .... 99
\(2*9*10^1=2*(99-10+1)\)

100 101 102 103 104 105 106 107 .....999
\(3*9*10^3=3*(999-100+1)\)

\(10^x\) \(10^x+1\) \(10^x+2\) \(10^x+3\) \(...10^{x+1}-1\)
\((x+1)*9*10^{x+1}=(x+1)*(10^{x+1}-1-10^x+1)\)

  • Order \ (i = 10 ^ {x }, j = x + 1 \)
  • The same number of each digit has \ (9 * i * 10 * j \) th encountered integer multiple of 10 it is not \ ((n-i + 1 ) * j \) th

Code 100

#include<iostream>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<cmath>
#define ll long long 
using namespace std;
ll n,x;
int T;
ll check1(ll x){
    ll now=0;
    for(ll i=1,j=1;i<=x;i*=10,j++){
        if(10*i<=x) now+=(9*i*(x-i*10+1)*j)+j*(9*i*(1+9*i))/2;
        else now+=j*(x-i+1)*(x-i+2)/2;
        if(now>1e18) return 1e18;
    }
    return now;
}
ll check2(ll x){
    ll now=0;
    for(ll i=1,j=1;i<=x;i*=10,j++){
        if(i*10<=x) now+=9*i*j;
        else now+=(x-i+1)*j;
        if(now>1e18) return 1e18;
    }
    return now;
}
int main()
{
    scanf("%d",&T);
    while(T--){
        scanf("%lld",&x);
        ll l=0,r=1e9,mid;
        while(l<=r){//二分组数 
            mid=(l+r)>>1;
            if(check1(mid)<x) l=mid+1;
            else r=mid-1;
        }
        x-=check1(r);
        r=l;
        l=1;
        while(l<=r){//二分组中的第几个数 
            mid=(l+r)>>1;
            if(check2(mid)<x) l=mid+1;
            else r=mid-1;
        }
        x-=check2(r);
        ll res=l,cnt=0;
        while(res){
            ++cnt;
            res/=10;
        }
        x=cnt-x;
        for(ll i=1;i<=x;i++) l/=10;
        printf("%lld\n",l%10); 
    }
    return 0;
}

Guess you like

Origin www.cnblogs.com/Vimin/p/11600788.html