[SDOI2015]約數個數和-[BZOJ4176]Lucas的數論-題解
題意簡述
給定,求下面式子的值,其中表示的約數個數。
其中
我們考慮將進行轉化,其實其值就相當於下面:
簡單證明:
由於其質因子之間會不影響,所以我們分開單獨考慮,對於一個的質因子,假設它在中為,那麼肯定有,所以我們考慮,對於一個因子,如果我們就在中選擇,此時,那麼由於對於這一個因子只能算一次,所以在中選了後就不能再中選擇,所以必須保證中沒有因子,而當時,我們就在中選擇指數為的,此時同樣要求中不包含因子,那麼將此情況應用到所有的質因子上,顯然,也就是,因此得證。
其實相當於一個對映,我們將,其中的對映到上去,而的對映到上,由於如果不互質,那麼相當於我們把同一個因子同時對映在了,會算多次,但是隻能算一次,所以要保證互質。
那麼我們就將式子轉換成了(這裡預設不滿足則交換):
由於的範圍比較小,我們線性篩出並預處理字首和,然後對於後面的我們令
其實我們容易知道:
簡單證明:
我們考慮,對於一個,它可以對其倍數,也就是,貢獻次,剛好反過來考慮,對於一個數,它的每個因子都會對其貢獻一次,所以原式就相等了。
原式就變成:
那麼我們再的線性篩出並預處理字首和,這個題就可以每次分塊的回答了。
複雜度
#include<cstdio>
#include<cstring>
#include<algorithm>
#define ll long long
using namespace std;
const int M=1e5+10;
int T,n,m;
ll prime[M],sdiv[M],num[M],cnt,mob[M];
bool nop[M];
void init(int n){
sdiv[1]=1;num[1]=1;mob[1]=1;
for(int i=2;i<=n;i++){
if(!nop[i]) prime[++cnt]=i,sdiv[i]=2,num[i]=1,mob[i]=-1;
for(int j=1;j<=cnt&&i*prime[j]<=n;j++){
nop[i*prime[j]]=1;
if(i%prime[j]){
sdiv[i*prime[j]]=sdiv[i]*sdiv[prime[j]];
num[i*prime[j]]=1;
mob[i*prime[j]]=-mob[i];
}else{
sdiv[i*prime[j]]=sdiv[i]/(num[i]+1)*(num[i]+2);
num[i*prime[j]]=num[i]+1;
mob[i*prime[j]]=0;
break;
}
}
}
for(int i=1;i<=n;i++) sdiv[i]+=sdiv[i-1],mob[i]+=mob[i-1];
}
ll calc(int n,int m){
int pos;if(n>m) swap(n,m);
ll ans=0;
for(int i=1;i<=n;i=pos+1){
int t1=n/i,t2=m/i;
pos=min(n/(t1),m/(t2));
ans+=(mob[pos]-mob[i-1])*(sdiv[t1])*(sdiv[t2]);
}
return ans;
}
int main(){
scanf("%d",&T);
init(50000);
while(T--){
scanf("%d%d",&n,&m);
printf("%lld\n",calc(n,m));
}
return 0;
}
加強版【BZOJ4176-許可權題】
一組詢問,給定,求下面式子的值:
此時無法的線性篩,所以我們要換個角度考慮,可能要用杜教篩或其他低於線性的篩法。
我們先來看,對於一個,我們令,此時顯然,然後肯定有(是顯然的,而由於而,只是除去了在中的因子,所以肯定)。
另外一種解釋:,,因為,所以。
所以,對於任意的都有,由此可知:
這個也就是前面的另一種數學的證明方法,再說一遍而已XD
我們看原來化簡到最後的式子,此時就變成了:
對於的字首和我們用杜教篩就可以了,而對於的值,我們預處理個,然後每次呼叫到更大的,現場數論分塊的算就好啦,記憶化一下。
由於杜教篩中也有數論分塊,所以複雜度還是,那麼這個題就解決了。
程式碼,先咕咕一會兒XD
End
一道類似的題目【51Nod1220約數之和】-【題解】
相關文章
- P3327 [SDOI2015] 約數個數和
- 數論——質數與約數
- [Lucas定理] 集合計數
- 約數個數定理
- [BZOJ3601]一個人的數論-題解
- 怎樣解題|題7.5.12:因數的個數
- 51Nod1220約數之和-數論
- 51Nod1584 加權約數和-題解
- 【JAVA習題六】輸入兩個正整數m和n,求其最大公約數Java
- 最大公約數和最小公倍數
- 最小公倍數和最大公約數
- 【數學問題】最大公約數與最小公倍數
- 「數論難題解答」
- 數論——數論分塊
- 洛谷P1403 [AHOI2005]約數研究【數論】
- 統計輸入的數字為正數和負數的個數
- 質數與約數
- C語言基礎 求出兩個數的公約數C語言
- 約數
- 數論(1):素數
- 數學 之 數論
- 樹刷題題後感——相對來說概念和公式數量可以和數論比較公式
- P7575 「PMOI-3」公約數 題解
- 求最大公約數 & 最大公約數
- 51nod“省選”模測第二場 B 異或約數和(數論分塊)
- 數論概論中的費馬降階法求一個質數分解成2個數的平方和與窮舉法的效率比較
- 數列 題解
- 數論
- LeetCode題解(1512):好數對的數目(Python)LeetCodePython
- 數學——數論/雜項
- 【數論】素數篩法
- 【題解】A23329.等差數列計數
- 【數學問題】判斷一個數是否是素數
- 求兩個正整數的最大公約數與最小公倍數--C#實現C#
- 約數研究
- P5655 基礎數論函式練習題 題解函式
- 洛谷題單指南-數學基礎問題-P1029 [NOIP2001 普及組] 最大公約數和最小公倍數問題
- 數學 in OI-數論-1