Hướng dẫn giải của Tresnja


Chỉ dùng lời giải này khi không có ý tưởng, và đừng copy-paste code từ lời giải này. Hãy tôn trọng người ra đề và người viết lời giải.
Nộp một lời giải chính thức trước khi tự giải là một hành động có thể bị ban.

Lưu ý: Các code mẫu dưới đây chỉ mang tính tham khảo và có thể không AC được bài tập này

Code mẫu của flashmt

const maxl=16;
var l:longint; a,b:int64;
    f:array[0..maxl,0..9,1..maxl] of int64;
    s:array[0..maxl,0..9] of int64;
    sum,e:array[0..maxl] of int64;
    p,pp:array[-1..maxl] of int64;
    d:array[1..maxl] of longint;

procedure init;
var i,j:longint;
begin
     p[-1]:=0; p[0]:=1; p[1]:=9;
     pp[-1]:=0; pp[0]:=1; pp[1]:=10;
     for i:=2 to maxl do
     begin
          p[i]:=p[i-1]*10;
          pp[i]:=pp[i-1]*10;
     end;
end;

procedure dp;
var i,j,k:longint;
begin
     for j:=0 to 9 do
     begin
          f[1,j,1]:=j;
          s[1,j]:=j;
          sum[1]:=sum[1]+j;
     end;
     for i:=2 to maxl do
     begin
          for j:=0 to 9 do
          begin
               f[i,j,1]:=sum[i-1]-s[i-1,j]+p[i-1]*j;
               s[i,j]:=s[i,j]+f[i,j,1];
          end;
          for j:=0 to 9 do
              for k:=2 to i do
              begin
                   f[i,j,k]:=f[i-1,j,k-1]+j*(k shl 1-1)*p[i-k];
                   s[i,j]:=s[i,j]+f[i,j,k];
              end;
          for j:=0 to 9 do sum[i]:=sum[i]+s[i,j];
     end;
end;

procedure dem(a:int64;x:longint);
var i:longint; t,u,tt:int64;
begin
     e[0]:=a+1; t:=0; tt:=0;
     u:=pp[l-x+1]*d[x-1];
     for i:=1 to l-x+1 do
     begin
          u:=u div 10;
          t:=t+u; tt:=t+pp[l-x-i+1];
          if a<t then e[i]:=0
          else
              if a>=tt then e[i]:=pp[l-x-i+1]
              else e[i]:=a-t+1;
          e[i-1]:=e[i-1]-e[i];
     end;
end;

function calc(a:int64):int64;
var i,j,k:longint; re:int64; st:string;
begin
     re:=0; calc:=0;
     if a=0 then exit;
     str(a,st); l:=length(st);
     for i:=1 to l do d[i]:=ord(st[i])-48;
     for j:=0 to d[1]-1 do
         re:=re+s[l,j];
     a:=a mod pp[l-1];
     for i:=2 to l do
     begin
          fillchar(e,sizeof(e),0);
          dem(a,i);
          for k:=0 to l-i+1 do
              re:=re+d[i-1]*(k shl 1+1)*e[k];
          for j:=0 to d[i]-1 do
              re:=re+s[l-i+1,j];
          a:=a mod pp[l-i];
     end;
     re:=re+d[l];
     calc:=re;
end;

begin
     init;
     dp;
     read(a,b);
     writeln(calc(b)-calc(a-1));
end.

Code mẫu của ladpro98

#include <bits/stdc++.h>

using namespace std;

vector<int> D;
long long power[19];
long long memo[19][10][19][2];
long long value[19];

long long dp(int i, int digit, int cnt, bool smaller) {
    if (i < 0) return digit * cnt * cnt;
    long long &ans = memo[i][digit][cnt][smaller];
    if (ans != -1) return ans;
    ans = 0;
    for (int now = 0, limit = smaller ? 9 : D[i]; now <= limit; ++now) {
        if (now != digit) {
            long long mul;
            if (smaller || (now < D[i]))
                mul = power[i];
            else
                mul = i ? (value[i - 1] + 1) : 1;
            ans += dp(i - 1, now, 1, smaller || (now < D[i])) + mul * digit * cnt * cnt;
        } else {
            ans += dp(i - 1, now, cnt + 1, smaller || (now < D[i]));
        }
    }
    return ans;
}

long long solve(long long x) {
    if (x == 0) return 0;
    D.clear();
    while (x > 0) {
        D.push_back(x % 10);
        x /= 10;
    }
    value[0] = D[0];
    for (int i = 1; i < D.size(); ++i)
        value[i] = power[i] * D[i] + value[i - 1];
    memset(memo, -1, sizeof(memo));
    return dp(D.size() - 1, 0, 0, 0);
}


int main() {
    ios::sync_with_stdio(0); cin.tie(0);
    power[0] = 1;
    for (int i = 1; i < 19; ++i) power[i] = power[i - 1] * 10;
    long long A, B;
    cin >> A >> B;
    cout << solve(B) - solve(A - 1) << endl;
    return 0;
}

Code mẫu của RR

#include <iostream>
#include <algorithm>

#define FOR(i,a,b) for(long i=a; i<=b; i++)
#define DOW(i,a,b) for(long i=a; i>=b; i--)
#define ll long long
using namespace std;

ll a,b,f[20][10][20][2],sl[20][10][20][2];
long cs[20];

void ptich(ll b) {
    memset(cs,0,sizeof cs);
    DOW(i,16,1) {
        cs[i]=b%10;
        b/=10;
    }
}

void update(long i,long last,long len,long ok1,long next,long ok2) {
    if (!sl[i][last][len][ok1]) return ;
    ll tmp=0LL;
    long len2;
    if (next==last) len2=len+1;
    else {
        len2=1;
        tmp=last*len*len;
    }

    f[i+1][next][len2][ok2]+=f[i][last][len][ok1]+tmp*sl[i][last][len][ok1];
    sl[i+1][next][len2][ok2]+=sl[i][last][len][ok1];
}

ll get(ll b) {
    if (!b) return 0LL;
    memset(sl,0,sizeof sl);
    memset(f,0,sizeof f);

    b=b*10+1;
    ptich(b);

    FOR(now,0,cs[1]-1) {
        f[1][now][1][1]=0LL;
        sl[1][now][1][1]=1LL;
    }
    f[1][cs[1]][1][0]=0LL;
    sl[1][cs[1]][1][0]=1LL;

    FOR(i,1,15)
    FOR(last,0,9)
    FOR(len,1,i) {
        FOR(next,0,9)
            update(i,last,len,1,next,1);
        FOR(next,0,cs[i+1]-1)
            update(i,last,len,0,next,1);
        update(i,last,len,0,cs[i+1],0);
    }

    ll res=0;
    FOR(len,1,16) res+=f[16][0][len][1];
    return res;
}

int main() {
//    freopen("input.txt","r",stdin);
//    freopen("output.txt","w",stdout);
    cin >>a >>b;
    ll tmp=0;
    if (b==1000000000000000LL) {
        tmp=1LL;
        b-=1LL;
    }
    cout<<get(b)-get(a-1);
    return 0;
}

Code mẫu của hieult

#include <cstdio>
#include <cstring>
//#include <iostream>
//#include <conio.h>
#include <algorithm>

using namespace std;

typedef long long ll;

ll A,B,mu10[17],f[17][12];

ll tim(int n,ll mu)
{
     if(n<0) return 0;
     ll u = max(mu*mu10[n],A);
     ll v = min((mu+1)*mu10[n]-1,B);
     if(u>v) return 0;
     return v-u+1;
}

ll xuly(int n, int so, ll mu)
{
     ll minn = mu*mu10[n];ll maxx = (mu+1)*mu10[n]-1;
     if(minn > B || maxx <A) return 0;
     if(minn >= A && maxx <= B && f[n][so] != -1) return f[n][so];
     ll kq = 0;
     for(int i = 0;i<=9;i++)
     {
          if(i== so) continue;
          ll t = mu;
          for(int k = 1;k<=n;k++)
          {
               t = t*10+i;
               kq = kq+i*k*k*(tim(n-k,t)-tim(n-k-1,t*10+i))+xuly(n-k,i,t);
          }
     }
     if(minn >= A && maxx <= B) f[n][so] = kq;
     return kq;
}

int main()
{

    scanf("%lld %lld",&A,&B);
    mu10[0] = 1;
    for(int i = 1;i<=15;i++) mu10[i] = mu10[i-1]*10;
    memset(f,-1,sizeof(f));
    printf("%lld\n",xuly(15,10,0));
    //getch();
}

Code mẫu của ll931110

#include <algorithm>
#include <bitset>
#include <cmath>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <deque>
#include <fstream>
#include <iostream>
#include <iterator>
#include <map>
#include <queue>
#include <set>
#include <sstream>
#include <string>
#include <vector>
typedef long long ll;
using namespace std;

ll mem[16][11];
ll p10[16];
ll A,B;

ll calc(int n,ll prefix)
{
   if (n < 0) return 0;
   ll low = max(p10[n] * prefix,A);
   ll high = min(p10[n] * (prefix + 1) - 1,B);
   return (low > high) ? 0 : (high - low + 1);
};

ll rec(int n,int prev,ll prefix)
{
   ll low = p10[n] * prefix;
   ll high = p10[n] * (prefix + 1) - 1;
   if (high < A || B < low) return 0;
   if (A <= low && high <= B && mem[n][prev] != -1) return mem[n][prev];
   ll ret = 0;
   for (int digit = 0; digit < 10; digit++) if (digit != prev)
   {
       ll t = prefix;
       for (int k = 1; k <= n; k++)
       {
           t = t * 10 + digit;
           ret += digit * k * k * (calc(n - k,t) - calc(n - k - 1,t * 10 + digit)) + rec(n - k,digit,t);
       };
   };   
   if (A <= low && high <= B) mem[n][prev] = ret;  return ret;
};

int main()
{
//    freopen("tres.in","r",stdin);
//    freopen("tres.ou","w",stdout);
    cin >> A >> B;
    p10[0] = 1;
    for (int i = 1; i <= 15; i++) p10[i] = p10[i - 1] * 10;
    memset(mem,-1,sizeof(mem));
    cout << rec(15,10,0) << endl;
};

Code mẫu của khuc_tuan

#include <iostream>
using namespace std;

int a[22], na;
long long F[18][2][18][18];
long long pow10[18], value[18];

long long go(int pos, int isless, int last, int len) {
    if(pos==-1) return last * len * len;
    long long &ret = F[pos][isless][last][len];
    if(ret!=-1) return ret;
    ret = 0;
    for(int ad=0;ad<10;++ad)
        if(isless || ad <= a[pos])
            ret += go( pos - 1, isless || ad < a[pos], ad, (ad==last) ? (len + 1) : 1) + ((ad==last) ? 0 : (last * len * len)) * ((isless || ad < a[pos]) ? pow10[pos] : value[pos]);
    return ret;
}

long long calc(long long X) {
    if(X==0) return 0;
    na = 0;
    for(;X!=0;X/=10) a[na++] = X % 10;
    value[0] = 1;
    value[1] = a[0];
    for(long long i=1, hs = 10;i<na;++i, hs *= 10) value[i+1] = value[i] + a[i] * hs;
    for(int i=1;i<=na;++i) value[i] ++ ;
    memset( F, -1, sizeof(F));
    return go( na - 1, 0, 0, 0);
} 

int main() {
    pow10[0] = 1;
    for(int i=1;i<18;++i) pow10[i] = 10 * pow10[i-1];
    long long A, B;
    cin >> A >> B;
    cout << calc(B) - calc(A-1) << endl;
    return 0;
}

Bình luận

Hãy đọc nội quy trước khi bình luận.


Không có bình luận tại thời điểm này.