P6156 简单题(推式子&莫反&整除分块)
Posted Harris-H
tags:
篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了P6156 简单题(推式子&莫反&整除分块)相关的知识,希望对你有一定的参考价值。
P6156 简单题(推式子&莫反&整除分块)
https://www.luogu.com.cn/problem/solution/P6156
// Problem: P6156 简单题
// Contest: Luogu
// URL: https://www.luogu.com.cn/problem/P6156
// Memory Limit: 250 MB
// Time Limit: 1000 ms
// Date: 2021-07-07 21:28:20
// --------by Herio--------
#include<bits/stdc++.h>
using namespace std;
typedef long long ll;
typedef unsigned long long ull;
const int N=1e7+10,M=2e4+5,inf=0x3f3f3f3f,mod=998244353;
#define mst(a,b) memset(a,b,sizeof a)
#define PII pair<int,int>
#define fi first
#define se second
#define pb emplace_back
#define SZ(a) (int)a.size()
#define ios ios::sync_with_stdio(false),cin.tie(0)
void Print(int *a,int n){
for(int i=1;i<n;i++)
printf("%d ",a[i]);
printf("%d\\n",a[n]);
}
int p[N],cnt;
bitset<N>vis;
ll f[N],F[N];
ll ksm(ll a,ll n,ll m=mod){
ll ans=1;
while(n){
if(n&1) ans=ans*a%m;
a=a*a%m;
n>>=1;
}
return ans;
}
ll n,k;
void init(int n){
vis[1]=F[1]=f[1]=1;
for(int i=2;i<=n;i++){
if(!vis[i]) p[++cnt]=i,f[i]=i-1,F[i]=ksm(i,k,mod);
for(ll j=1;j<=cnt&&i*p[j]<=n;j++){
vis[i*p[j]]=1;
F[i*p[j]]=F[i]*F[p[j]]%mod;
if(i%p[j]==0){
int x=i/p[j];
if(x%p[j]) f[i*p[j]]=(mod-p[j])*f[x]%mod;
break;
}
f[i*p[j]]=f[i]*f[p[j]]%mod;
}
}
for(int i=1;i<=n;i++) f[i]=(f[i-1]+f[i]*F[i]%mod)%mod,F[i]=(F[i]+F[i-1])%mod;
for(int i=1;i<=n;i++) F[i]=(F[i]+F[i-1])%mod;
}
ll fun(ll n){
return ((F[n<<1]-(F[n]<<1))%mod+mod)%mod;
}
ll solve(ll n){
ll s=0;
for(ll l=1,r;l<=n;l=r+1){
r=n/(n/l);
s+=fun(n/l)*(f[r]-f[l-1]+mod)%mod;
s%=mod;
}
return s;
}
int main(){
scanf("%lld%lld",&n,&k);
k%=(mod-1);
init(N-1);
printf("%lld\\n",solve(n));
return 0;
}
以上是关于P6156 简单题(推式子&莫反&整除分块)的主要内容,如果未能解决你的问题,请参考以下文章
bzoj 3157 && bzoj 3516 国王奇遇记——推式子