P12397 函数大师
题意
令 \(\displaystyle s(n)=\sum_{i=0}^{+\infty}(\lfloor\frac{n}{10^i}\rfloor\bmod 10)\),即 \(n\) 在十进制下各位数字之和;
令 \(S_k(n)=\begin{cases}n,&k=0\\s(S_{k-1}(n)),&k>0\end{cases}\);
令 \(\displaystyle f_k(n)=\sum_{i=0}^kS_i(n)\)。
对于一个固定的 \(k\)(\(0\le k\le10^9\)),每次询问给出一个 \(m\)(\(1\le m\le10^{18}\)),求存在多少个 \(n\),使得 \(f_k(n)=m\)。
询问数量 \(1\le q\le10^5\)。
思路
显然,满足条件的 \(n\le m\),所以 \(n\le10^{18}\)。
所以 \(S_1(n)\le162,S_2(n)\le18,S_3\le9,\forall i>3,S_i(n)=S_3(n)\)。
考虑枚举 \(S_1(n)\),并算出 \(sum=\displaystyle\sum_{i=1}^kS_i(n)\),若 \(s(m-sum)=S_1(n)\),则 \(n=m-sum\) 是一个解。
当 \(k=0\) 时,直接输出 \(1\) 即可。
程序
#include<cstdlib>
#include<algorithm>
#include<cstdio>
#include<cstring>
#include<queue>
#include<cstdio>
#include<iostream>
#include<vector>
#include<map>
#include<cmath>
#include<iomanip>
#include<string>
#include<stack>
#include<unordered_map>
#include<complex>
#define ll long long
#define ull unsigned long long
#define uint unsigned int
#define vl __int128
#define ld long double
#define INF 0x3f3f3f3f
#define eps 1e-9
#define ls rt<<1
#define rs rt<<1|1
#define fir first
#define sec second
#define lb(x) ((x)&(-(x)))
#define pb push_back
#define pii pair<int,int>
#define pdi pair<double,int>
#define forUp(i,a,b) for(int i=(a);i<=(b);++i)
#define forDown(i,a,b) for(int i=(a);i>=(b);--i)
template<typename T>inline void chkMax(T &x,T y){if(x<y)x=y;}
template<typename T>inline void chkMin(T &x,T y){if(x>y)x=y;}
template<typename T>inline void addMod(T &x,T y,T mod){if((x+=y)>=mod)x-=mod;}
template<typename T>inline void subMod(T &x,T y,T mod){if((x-=y)<0)x+=mod;}
using namespace std;
const int N=0+10;
//#define use_file
//#define more_test
//#define need_init
#ifdef more_test
int T;
#endif
ll T,k;ll m;
ll s(ll n){
ll ans=0;
while(n>0)ans+=n%10,n/=10;
return ans;
}
ll ans,S[163];
void SOLVE(/*int TestID*/){
scanf("%lld%lld",&T,&k);
if(k==0){
while(T--){
scanf("%lld",&m);
printf("1\n");
}
return;
}
forUp(i,1,162)S[i]=s(i);
if(k==1){
while(T--){
scanf("%lld",&m);
ans=0;
forUp(i,1,162)if(s(m-i)==i)++ans;
printf("%lld\n",ans);
}
return;
}
if(k==2){
while(T--){
scanf("%lld",&m);
ans=0;
forUp(i,1,162)if(s(m-i-S[i])==i)++ans;
printf("%lld\n",ans);
}
return;
}
while(T--){
scanf("%lld",&m);
ans=0;
forUp(i,1,162)if(s(m-i-S[i]-(k-2)*S[S[i]])==i)++ans;
printf("%lld\n",ans);
}
}
/*
Input:
Output:
*/
int main(){
#ifdef use_file
freopen("test.in","r",stdin);
freopen("test.out","w",stdout);
#endif
#ifdef need_init
init();
#endif
#ifdef more_test
scanf("%d",&T);
for(int i=1;i<=T;++i)SOLVE(/*i*/);
#else
SOLVE();
#endif
return 0;
}

浙公网安备 33010602011771号