1. 程式人生 > >2016 ccpc 杭州 D.Difference hdu5936

2016 ccpc 杭州 D.Difference hdu5936

  • 題意:
    • f(y,k)=z in every digits of yZk(e.g.f(233,2)=22+32+32=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)
    • x=f(y,k)y(1)x=f(y,k)-y\quad(1)
      已知 x 和 k ,求符合上式的 y 的個數
  • 坑點:注意題中表明 y 為正數, 即 y>0
  • 演算法:折半列舉。手動模擬得y<=1e10, 令y=a+b1e5(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)帶入式(1)得x=f(a,k)a+f(b,k)b1e5x=f(a,k)-a+f(b,k)-b*1e5
    xf(a,k)+a=f(b,k)b1e5x-f(a,k)+a=f(b,k)-b*1e5預處理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 */