题解:P10704 救赎(Redemption)
题目传送门。
思路
容易得到
由于传入函数
那么
最终答案就是:
时间复杂度
#include <bits/stdc++.h>
#define ll long long
using namespace std;
const int Maxn=1e6+7;
const int Mod=998244353;
ll n,m;
ll a[Maxn];
ll sq;
ll ans;
ll sq1[Maxn],sq2[Maxn];
ll bb[Maxn];
inline ll Gt(ll x){
if(x==0) return 0;
if(x<=sq) return sq1[x];
else return sq2[m/x];
}
map<ll,ll>S;
inline ll KP(ll x){
if(S.count(x)) return S[x];
ll res=0;
ll pp=__builtin_sqrt(x);
for(ll i=1;i<=pp;i++)
res=(res+bb[i]*(Gt(x/i)-Gt(i)))%Mod;
res=res*2%Mod;
for(ll i=1;i<=pp;i++) res=(res+bb[i]*bb[i])%Mod;
return S[x]=res;
}
int main(){
scanf("%lld%lld",&n,&m);
sq=sqrt(m);
for(int i=1;i<=n;i++){
scanf("%lld",&a[i]);
if(a[i]<=sq) bb[a[i]]++;
}
sort(a+1,a+n+1);
for(ll l=1,r;l<=m;l=r+1){
r=m/(m/l);
int res=upper_bound(a+1,a+n+1,r)-a-1;
if(r<=sq) sq1[r]=res;
else sq2[m/r]=res;
}
for(ll l=1,r;l<=m;l=r+1){
r=m/(m/l);
ans=(ans+(KP(r)-KP(l-1))%Mod*(m/l)%Mod)%Mod;
}
ans=(ans+Mod)%Mod;
printf("%lld",ans);
return 0;
}