P5842

本文详细探讨了如何使用C++语言实现各种数据结构和算法,包括常见数据结构的操作和经典算法的实现,旨在提升读者在算法和数据结构方面的理解和应用能力。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

#include <iostream>
#include <cstdio>
#include <cstring>

#define int long long // QAQ_QWQ

using namespace std;

const int MOD = 20120427, isoprene_jvruoMOD = 1000037, N = 66062;

#define ll long long

int head[isoprene_jvruoMOD + 50], num, f[20][N], g[20][N], cnt, c[20], isoprene_akioi[20], h[22][2][2][2], sum[22][2][2][2];

struct Node
{
    int next;
    ll c;
} isoprene_jvruo[isoprene_jvruoMOD + 10];

template <typename T>
void Read(T &x)
{
    x = 0; int p = 0; char gg = getchar();
    while (gg < '0' || gg > '9') p = (gg == '-'), gg = getchar();
    while (gg >= '0' && gg <= '9') x = (x << 1) + (x << 3) + (gg ^ '0'), gg = getchar();
    x = p ? -x : x;
    return;
}

template <typename T>
void Put(T x)
{
    if (x < 0) putchar('-'), x = -x;
    if (x > 9) Put(x / 10);
    putchar(x % 10 + '0');
    return; 
}

int Ins(ll x)
{
    int bh = x % isoprene_jvruoMOD;
    for (int i = head[bh]; i; i = isoprene_jvruo[i].next)
        if (isoprene_jvruo[i].c == x)
            return i;
    isoprene_jvruo[++ num] = (Node) {head[bh], x};
    head[bh] = num;
    return num;
} 

int Ask(ll x)
{
    int bh = x % isoprene_jvruoMOD;
    for (int i = head[bh]; i; i = isoprene_jvruo[i].next)
        if (isoprene_jvruo[i].c == x)
            return i;
    return 0;
}

void rr()
{
    isoprene_akioi[0] = 1;
    for (int i = 1; i <= 18; i ++)
        isoprene_akioi[i] = (isoprene_akioi[i - 1] * 10) % MOD;
    int tmp;
    f[0][Ins(1)] = 1;
    for (int i = 0; i < 18; i ++)
        for (int j = 1; j <= num; j ++)
            for (int k = 1; k <= 9; k ++)
            {
                if (isoprene_jvruo[j].c * k > 1000000000000000000LL)
                    break;
                (f[i + 1][tmp = Ins(isoprene_jvruo[j].c * k)] += f[i][j]) %= MOD;
                (g[i + 1][tmp] += g[i][j] * 10 % MOD + f[i][j] * k) %= MOD;
            }
    return;
} 

int Work(ll x, ll k)
{
    cnt = 0;
    int m = 0;
    while (x)
    {
        c[++ cnt] = x % 10;
        x /= 10;
    }
    ll ans = 0, pre = 0, mul = 1;
    for (int i = cnt; i; i --)
    {
        if (! c[i])
            break;
        for (int j = 1; j < c[i]; j ++)
            if ((k % (mul * j)) == 0)
            {
                ll tmp = k / mul / j;
                int t = Ask(tmp);
                (ans += ((pre << 3) + (pre << 1) + j) * isoprene_akioi[i - 1] % MOD * f[i - 1][t] % MOD + g[i - 1][t]) %= MOD;
            }
        pre = (pre << 3) + (pre << 1) + c[i];
        mul *= c[i];
    }
    int tmp = Ask(k);
    for (int i = 1; i < cnt; i ++)
        (ans += g[i][tmp]) %= MOD;
    return ans;
}

int Work0(ll x)
{
    cnt = 0;
    memset(h, 0, sizeof(h));
    memset(sum, 0, sizeof(sum));
    while (x)
    {
        c[++ cnt] = x % 10;
        x /= 10;
    }
    h[cnt + 1][1][0][0] = 1;
    for (int i = cnt + 1; i >= 2; i --)
    {
        if (cnt + 1 
        != i)
        h[i][0][0][0] = 1;
        for (int j = 0; j <= 1; j ++)
            for (int t = 0; t <= 1; t ++)
                for (int q = 0; q <= 1; q ++)
                    if (h[i][j][t][q])
                        for (int k = 0; k <= 9; k ++)
                        {
                            if (j && k > c[i - 1])
                                break;
                            if (! t && ! q && ! k)
                                continue;
                            (h[i - 1][j && (k == c[i - 1])][t || (! k)][q || k] += h[i][j][t][q]) %= MOD; 
                            (sum[i - 1][j && (k == c[i - 1])][t || (! k)][q || k] += sum[i][j][t][q] * 10 + h[i][j][t][q] * k) %= MOD;
                        }
    }
    return (sum[1][1][1][1] + sum[1][0][1][1]) % MOD;
}

inline bool only(long long k) {
    while (k % 2 == 0)
        k /= 2;
    while (k % 3 == 0)
        k /= 3;
    while (k % 5 == 0)
        k /= 5;
    while (k % 7 == 0)
        k /= 7;
    if (k == 1)
        return true;
    else
        return false;
}

signed main()
{
    rr();
    int t;
    ll l, r, k;
    Read(t);
    while (t --)
    {
        Read(l);
        Read(r);
        Read(k);
        if (k) {
            Put(((Work(r + 1, k) - Work(l, k)) % MOD + MOD) % MOD), putchar('\n');
        }
        else {
            Put(((Work0(r) - Work0(l - 1)) % MOD + MOD) % MOD), putchar('\n');
        }
    }
    return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值