这道题挺有意思的;如果够聪明的话直接可以大概猜出来结果;但是我没那么聪明,嘻嘻;
这道题一看两个连加符号:
然后n又是1e5,然后nn肯定就爆了,所以枚举肯定不行,所以只有走找规律的这条路了;
根据他的f函数定义,可以知道这个结论:
为什么有这个东东呢?
可以这样想,因为每次a1都会遍历所有的aj,a2也同理…an也同理;我可以这样想:有点像错位相加的感觉(因为这个每个数的长度相等):
那么就有:
是不是就相当于,把111变成111111,222变成222222,意思就是每个数字重复两次相加;
所以可以得到上面的结论;
但是怎么把两个连加符号写成一个呢?
可以这样理解:
当a1枚举到a2的时候,是不是当a2的时候就会枚举到a1去(绿色的那根)?;
所以根据上面的推论公式可以知道:
以这个规律下去,可以发现:
出现了n次,同理f(an,an)也会出现n次,所以总得和就是所有的相加n;
注意:在算重复数字的时候需要取Mod(因为有Mod的性质可以知道)
AC代码:
#include<bits/stdc++.h>
using namespace std;
#define Mod 998244353
#define M 100050
typedef long long ll;
ll F(ll a){
ll t=a,tt=a;
ll num=0;
while(tt){
num++;//算位数
tt/=10;
}
ll temp[20];//因为最多才20位;
ll i=0;
for(int j=0;j<num;j++){
temp[i++]=t%10;
temp[i++]=t%10;
t/=10;
}
ll res=0;//算结果
for(int k=2*num-1;k>=0;k--){
res=res*10+temp[k];
res%=Mod;//注意这里需要取模(因为我平常没怎么用过这种性质(只是常用+ - * /的Mod的性质))
}
return res%Mod;
}
int main(){
ll n,a[M];
scanf("%lld",&n);
for(int i=0;i<n;i++)scanf("%lld",a+i);
ll ans=0;
for(int i=0;i<n;i++){
ans=(ans+F(a[i]))%Mod;
// cout<<F(a[i])<<endl;
}
printf("%lld\n",ans*n%Mod);
return 0;
}