AT_abc357_d [ABC357D] 88888888

image

由于忘记等比数列求和公式痛失 D 题。


我们先按题意进行模拟。

\(k=\log_{10}n\),可得最后的 \(ans=(n\times k+n)\times k+n...\)

我们可以把 \(\times k+n\) 认为把当前数字向左移动 \(k\) 位并放置一个 \(n\),当然,最后一次放置不需要再向左移动。

将上式展开可得 \(ans=\sum \limits _{i=0}^{n-1} n\times k^i=n\times \sum \limits _{i=0}^{n-1} k^i\)

\(\sum \limits _{i=0}^{n-1} k^i\) 显然是等比数列,可以用 \(S=\frac{k^n-1}{k-1}\)\(O(1)\) 求出。(这个柿子是经过 \(\frac{a_nq-a_1}{q-1}\) 简化而来,更详细的等差数列推导可看百度百科

本题有模数 \(998244353\),用逆元处理乘法即可。不推荐使用 c++ 自带的 log10 函数。

code:

#include<iostream>
#include<algorithm>
#define mod 998244353
#define int __int128
//#include<bits/stdc++.h>
//using namespace std;
long long n;
inline int read(){
	int s=0;
	int w=1;
	char ch=getchar();
	for(;ch<'0'||ch>'9';ch=getchar())
    	if(ch=='-')
			w=-1;
	for(;ch>='0' and ch<='9';ch=getchar())
		s=s*10+ch-'0';
	return s*w;
}

void write(int x){
	if(x<0){
   		putchar('-');
   		x=-x;
	}
	if(x>9)
    	write(x/10);
	putchar(x%10+'0');
	return;
}//快读快写
int logd(int x){
	int cnt=0;
	while(x){
		x/=10;
		cnt++;
	}
	return cnt;
}//代替log10函数
int qpow(int b,int p){
	int ans=1;
	int tmp=b;
	while(p){
		if(p&1)
			ans=ans*tmp%mod;
		tmp=tmp*tmp%mod;
		p>>=1;
	}
	return ans%mod;
}//快速幂
signed main(){
	n=read();
	int k=qpow(10,logd(n));
	write(n*(qpow(k,n)-1)%mod*(qpow(k-1,mod-2))%mod);//费马小定理求逆元
	return 0;//撒花!
}
posted @ 2024-07-22 22:21  立花廿七  阅读(5)  评论(0编辑  收藏  举报