P12397 函数大师

Luogu 链接

题意

\(\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\) 即可。

程序

AC 记录

#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;
}
posted @ 2025-05-03 19:57  LXcjh4998  阅读(25)  评论(0)    收藏  举报