1. 程式人生 > 實用技巧 >【HDU】5936 Difference 折半列舉

【HDU】5936 Difference 折半列舉

題目連結

題意

定義函式\(f(y,k)=\sum_{i 是y的每一位}i^k\),比如\(f(232,2)=2^2+3^2+2^2==22\)

\[x=f(y,k)-y \]

現在給出 x 和 k,問有多少個 y 滿足上述式子。

思路

剛做了HDU 5735 ,有點經驗了。

對於一個整數 y,我們分為前 5 位和後 5 位。

那麼

\[\begin{aligned} &f(y,k)-y\\ &=(f(a,k)+f(b,k))-(a*100000+b)\\ &=(f(a,k)-a*100000)+(f(b,k)-b)\\ \end{aligned} \]

那麼我們可以求出上面兩個括號內的所有值。

然後列舉其中一個值,二分另一個值。

注意 y 的值大於0,所以兩個式子不能同時為0,其實也就是特判一下 x==0的時候。

程式碼

/*
 * @Autor: valk
 * @Date: 2020-08-11 12:38:37
 * @LastEditTime: 2020-10-09 10:16:49
 * @Description: 如果邪惡  是華麗殘酷的樂章 它的終場 我會親手寫上 晨曦的光 風乾最後一行憂傷 黑色的墨 染上安詳
 */
#include <algorithm>
#include <iostream>
#include <map>
#include <math.h>
#include <queue>
#include <set>
#include <stack>
#include <stdio.h>
#include <string.h>
#include <string>
#include <vector>
#define pb push_back
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int mod = 1e9 + 7;
const int seed = 12289;
const double eps = 1e-6;
const int inf = 0x3f3f3f3f;
const int N = 1e5 + 10;
//
vector<ll> vec1, vec2;

ll qpow(ll a, ll b)
{
    ll ans = 1;
    while (b) {
        if (b % 2)
            ans *= a;
        a *= a;
        b /= 2;
    }
    return ans;
}

int main()
{
    ll T, cas = 0;
    scanf("%lld", &T);
    while (T--) {
        vec1.clear(), vec2.clear();
        ll x, k;
        scanf("%lld%lld", &x, &k);
        for (ll i = 0; i <= 99999; i++) {
            ll temp = i;
            ll sum1 = 0;
            while (temp) {
                sum1 += qpow(temp % 10, k);
                temp /= 10;
            }
            vec1.pb(sum1 - i), vec2.pb(sum1 - i * 100000);
        }
        sort(vec2.begin(), vec2.end());
        ll ans = 0;
        for (ll i = 0; i < vec1.size(); i++) {
            ll l = lower_bound(vec2.begin(), vec2.end(), x - vec1[i]) - vec2.begin();
            ll r = upper_bound(vec2.begin(), vec2.end(), x - vec1[i]) - vec2.begin();
            ans += r - l;
        }
        if(x==0){
            ans--;
        }
        printf("Case #%lld: %lld\n", ++cas, ans);
    }
    return 0;
}