题目
题解
①我们可以知道当
x≥2
时,
φ(x)
为偶数。
②我们亦可以知道当
gcd(x,y)=1
时,
gcd(x,y−x)=1
。
由①,②得,当
x≥2
时,
f(x)=x
。特别的,
f(1)=2
。
问题转换为
ΣRi=Lik(1特判)
新知识:拉格朗日插值法求自然数幂和。
这东西干嘛用?
假设有一个平面直角坐标系,那么有k+1个点
(x0,f(x0)),...,(xk,f(xk))
用这k+1个点就可以确定一个k次的多项式。
设
li(x)
表示拉格朗日基本多项式。
li(x)=Πk+1j=1,j≠ix−xjxi−xj
接下来说明
f(x)=Σk+2i=1f(i)⋅li(x)
为什么是对的。
首先
f(x)=Σxi=1ik
可以等于一个k+1次的关于x的多项式。
我们只要证明当
x=1...k+2
时式子成立,那么这个k+1次的多项式就是确定的。
我们可以知道当
x=xi
时,
li(x)=1
,否则
li(x)=0
。
(我们可以将x带进l_i(x)中,若
x≠xi
,那么l_i(x)的有一个分子的因式等于0。)
在这道题目中,
xi=i
,因为
f(1)...f(i)...f(k+2)
可求,每一个i都相当于多项式的图象经过的第i个点,所以
xi=i
。
因为只有
i=j
时,
f(j)∗li(j)≠0
所以等式的左边
f(i)=Σk+2j=1,j≠if(j)∗li(j)=f(i)
等于等式的右边。
得证。
证明的大致思路:确定对
x=1...k+2
成立→确定这个唯一的k+1次的多项式→确定f(n)
别忘记L=1时要特判。
代码
#include<iostream>
#include<cstdio>
#include<cstring>
#include<cmath>
#include<algorithm>
#define LL long long
#define N 1000010
#define mo 998244353
#define fo(i,a,b) for(i=a;i<=b;i++)
using namespace std;
LL i,L,R,x,k,sum1,sum2,sum;
LL n0,n1,n2;
LL jc[N],ny[N];
LL f[N];
LL ksm(LL x,LL y){
LL res=1;
for(;y;x=(x*x)%mo,y/=2)if(y&1)res=(res*x)%mo;
return res;
}
void get(){
LL i,temp;
jc[0]=jc[1]=ny[0]=ny[1]=1;
fo(i,2,1000002)jc[i]=(jc[i-1]*i)%mo;
fo(i,2,1000002)ny[i]=ksm(jc[i],mo-2);
temp=0;
fo(i,1,1000002){
temp=(temp+ksm(i,k))%mo;
f[i]=temp;
}
}
LL getsum(LL n){
if(n<=k+2)return f[n];
LL i,temp,temp1,inv,inv1,inv2,n0,n1,n2,sum3=0;
n0=1;
fo(i,1,k+2)n0=(n0*(n-i))%mo;
fo(i,1,k+2){
temp=(n0*f[i])%mo;
inv1=((jc[i-1]*(n-i))%mo*jc[k-i+2])%mo;
inv1=ksm(inv1,mo-2);
temp1=(temp*inv1)%mo;
if((k+2-i)&1)sum3=(sum3-temp1+mo)%mo;
else sum3=(sum3+temp1)%mo;
}
return sum3;
}
int main(){
freopen("count.in","r",stdin);
freopen("count.out","w",stdout);
scanf("%lld%lld%lld",&L,&R,&k);
get();
sum1=getsum(R);
sum2=getsum(L-1);
sum=(sum1-sum2+mo)%mo;
if(L==1)sum=(sum+ksm(2,k)-1+mo)%mo;
printf("%lld",sum);
return 0;
}