G. D-Function

原题链接

题解

先不考虑k的限制,而是考虑对于任意一个数,存不存在一个k使得题目所给等式成立
\(n·k\) 没有进位时,等式一定成立
(赛时也许想到这就够了)
假如有进位呢?

对于任何一个位数大于1的数,必有 \(D(n) \lt n\) (想想十进制是怎么表示数的)
而对于位数为1的数,有 \(D(n)=n\)
所以只要有一个进位,就相当于一个位数为1的数变成位数大于1的数,则 \(D(kn)\) 一定小于 \(k·D(n)\)

实施

求出最大的乘上k不会进位的数 \(m\)
然后求出 \([0,l]\)\([0,r]\) 内的有多少数,其所有位上的数不大于 \(m\)
之所以这么求是为了抵消前缀0的干扰

code

#include<bits/stdc++.h>
using namespace std;
#define ll long long
const ll mod=1e9+7;

inline void read(ll &x) {  
	x = 0;
	ll flag = 1;
	char c = getchar();
    while(c < '0' || c > '9'){
        if(c == '-')flag = -1;
        c = getchar();
    }
	while(c >= '0' && c <= '9') {
		x = (x << 3) + (x << 1) + (c ^ 48); 
		c = getchar();
	}
	x *= flag;
}

inline void write(ll x)
{
    if(x < 0){
    	putchar('-');
		x = -x;
	}
    if(x > 9) 
		write(x / 10);
    putchar(x % 10 + '0');
}

ll qpow(ll base, ll p) {
    ll res = 1, tem = base;
    while (p) {
        if (p & 1) res = (1LL * res * tem) % mod;
        p >>= 1;
        tem = (1LL * tem * tem) % mod;
    }
    return res;
}

int main() {
    ll t;
    read(t);
    while (t--) {
        ll l, r, k;
        read(l); read(r); read(k);

        ll m = 9 / k;
        ll res = (qpow(m + 1, r) - qpow(m + 1, l) + mod) % mod;
        write(res);
        putchar('\n');
    }
    return 0;
}

posted @ 2024-06-13 19:58  纯粹的  阅读(139)  评论(0)    收藏  举报