JZOJ 5395. 【NOIP2017提高A组模拟10.6】Count
生活随笔
收集整理的這篇文章主要介紹了
JZOJ 5395. 【NOIP2017提高A组模拟10.6】Count
小編覺得挺不錯的,現在分享給大家,幫大家做個參考.
Description
Input
一行三個正整數 ,表示 ��,��,��,含義如題所示。
Output
一行一個整數表示答案������ ������������������。
Sample Input
2 3 1
Sample Output
5
Data Constraint
Hint
≤��的正整數中與��互質的數有��,平均數×��=��
≤��的正整數中與��互質的數有��、��,平均數×��=��
Solution
考慮當 x≥2 時 φ(x) 為一個偶數,因為對于一個 ≤x 的正整數 y,
如果gcd(x,y)=1 則有 gcd(x,x?y)=1 。此時不難發現 f(x)=x 。
因此題目變成求:
∑i=LRik即自然數冪和!注意 f(1)=2 。不妨考慮:
∑i=1Rik于是我們可以使用拉格朗日插值法(這里不作證明,只講做法)。
對于 R 較小的情況,我們考慮快速冪直接計算。
對于 R 較大的情況,我們知道答案 ans(R) 是一個 k+1 次多項式。
根據拉格朗日插值法有:
ans(x)=∑i=1k+2ans(i)?∏k+2j=1,j≠i(x?j)∏k+2j=1,j≠i(i?j)枚舉 i,不難發現分子和分母都是連續兩段數字的乘積。
隨著 i 的增大,發現兩段數字只有端點的數字發生了變化。
時間復雜度 O(k?log?k) 。
Code
#include<cstdio> using namespace std; typedef long long LL; const int N=1e6+1,mo=998244353; int l,r,k; LL sum; LL ans[N]; inline LL ksm(LL x,int y) {LL s=1;x%=mo;while(y){if(y&1) s=s*x%mo;x=x*x%mo;y>>=1;}return s; } inline LL work(int x) {if(x<=k+2) return ans[x];LL num=0,a=1,b=1;for(int i=2;i<=k+2;i++){a=((x-i+mo)%mo*a)%mo;b=((1-i+mo)%mo*b)%mo;}for(int i=1;i<=k+2;i++){num=(num+ans[i]*a%mo*ksm(b,mo-2)%mo)%mo;a=(a*(x-i+mo)%mo*ksm(x-i-1+mo,mo-2))%mo;b=(b*i%mo*ksm(i-k-2+mo,mo-2))%mo;}return num; } int main() {scanf("%d%d%d",&l,&r,&k);for(int i=1;i<=k+2;i++) ans[i]=(ans[i-1]+ksm(i,k))%mo;sum=(work(r)+mo-work(l-1))%mo;if(l==1) sum=(sum+ksm(2,k)-1)%mo;printf("%lld",sum);return 0; }總結
以上是生活随笔為你收集整理的JZOJ 5395. 【NOIP2017提高A组模拟10.6】Count的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: JZOJ 5397. 【NOIP2017
- 下一篇: JZOJ 5396. 【NOIP2017