2016 ccpc 杭州 D.Difference hdu5936(折半枚举)

  • 题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=5936
  • 题意:
    • f ( y , k ) = ∑ z   i n   e v e r y   d i g i t s   o f   y Z k ( e . g . f ( 233 , 2 ) = 2 2 + 3 2 + 3 2 = 22 ) f(y, k) = \sum_{z\,in\,every\,digits\,of\,y} Z^{k} \quad(e.g.f(233,2) = 2^2 + 3^2 + 3^2 = 22) f(y,k)=zineverydigitsofyZk(e.g.f(233,2)=22+32+32=22)
    • x = f ( y , k ) − y ( 1 ) x=f(y,k)-y\quad(1) x=f(y,k)y(1)已知 x 和 k ,求符合上式的 y 的个数
  • 坑点:注意题中表明 y 为正数, 即 y>0
  • 算法:折半枚举。手动模拟得y<=1e10, 令 y = a + b ∗ 1 e 5 ( 1 &lt; = a &lt; = 99999 , 0 &lt; = b &lt; = 100000 ) y = a + b*1e5\quad(1&lt;=a&lt;=99999, 0&lt;=b&lt;=100000) y=a+b1e5(1<=a<=99999,0<=b<=100000)带入式(1)得 x = f ( a , k ) − a + f ( b , k ) − b ∗ 1 e 5 x=f(a,k)-a+f(b,k)-b*1e5 x=f(a,k)a+f(b,k)b1e5 x − f ( a , k ) + a = f ( b , k ) − b ∗ 1 e 5 x-f(a,k)+a=f(b,k)-b*1e5 xf(a,k)+a=f(b,k)b1e5预处理b,枚举a,即可在限制复杂度内求出答案。
    • 该算法减少了枚举 a 时,重复枚举 b 的运算量。
#include <bits/stdc++.h>
#define pi acos(-1);
#define fastio ios_base::sync_with_stdio(false);cin.tie(0);cout.tie(0);
using namespace std;
typedef long long LL;
typedef pair<int, int> PII;
const int INF = 0x3f3f3f3f;
const LL LL_INF = 0x3f3f3f3f3f3f3f3f;
const int maxn = 150000 + 10;
const int mod = 1e9 + 7;

map<LL, LL> mp[15];

LL F(LL y, LL k)
{
    LL tmp, ans=0, mul=1;
    while(y){
        tmp = y%10;
        mul = 1;
        for(LL i=1; i<=k; i++) mul *= tmp;
        ans += mul;
        y/=10;
    }
    return ans;
}

void init()
{
    for(LL k=1; k<=9; k++){
        for(LL i=0; i<100000; i++){
            mp[k][F(i, k)-i*100000]++;
            //if(F(i, k)-i*100000 == 0) printf("----%lld %lld\n", i, k);
        }
    }
}

int main()
{
    init();
    LL T, k, x, cas=0; scanf("%lld", &T);
    while(T--){
        scanf("%lld%lld", &x, &k);
        LL ans = 0;
        for(LL i=1; i<=99999; i++){
            if(mp[k].count(x-F(i, k)+i)){
                ans += mp[k][x-F(i, k)+i];
                //printf("...%lld\n", i);
            }
            //if(mp[k][x-F(i,k)+i]) printf("...%d %d %lld %lld\n", i, k, x-F(i, k)+i, mp[k][x-F(i,k)+i]);
        }
        printf("Case #%lld: %lld\n", ++cas, ans);
    }
}


/*
9
0 1
0 2
0 3
0 4
0 5
0 6
0 7
0 8
0 9

*/

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值