看了一下popoqqq爺的莫比烏斯反演,果斷棄療。還是寫遞推好,又短又快。
令f[i]表示當數不全相等時(為什麼如此,後面再說),最小公倍數為i*k的方案,那麼:
首先,當公倍數(注意不是最小)為i*k時,總方案數x^n-x,其中x表示l~r中i*k的倍數,再減去重複的方案:σ(u=2,i*k*u<=r-l)f[u*i],從而:
f[i]=x^n-x+σf[j](i|j)
注意到,由於f[i]表示數不全等時的方案,所以f[1]並不是最終方案。如果l<=k<=r,那麼答案還要再加上1。
實際上,如果沒有不全相等的條件,也是可做的,但是此時在上邊的遞推式中j的範圍需要超過r-l,會tle。(具體說不清楚,可以寫個程式測試一下)。
ac**如下:
#include#include#define ll long long
#define mod 1000000007
using namespace std;
int n,m,l,r,f[200005];
int ksm(int x,int y)
int main()
printf("%d\n",f[1]);
return 0;
}
by lych
2016.2.3
bzoj3930 數論 選數
description 我們知道,從區間 l,h l和h為整數 中選取n個整數,總共有 h l 1 n種方案。小z很好奇這樣選出的數的最大公約數的規律,他決定對每種方案選出的n個整數都求一次最大公約數,以便進一步研究。然而他很快發現工作量太大了,於是向你尋求幫助。你的任務很簡單,小z會告訴你乙個整數...
BZOJ3930 選數(莫比烏斯反演,杜教篩)
給定n,k,l,r 問從l r中選出 n 個數,使得他們gc d k的方案數 這樣想,既然gc d k 首先就把區間縮小一下 這樣變成了gc d 1 設f i 表示gc d 恰好為 i 的方案數 那麼,要求的是f 1 設g x d x f d 所以g x 表示x gcd 的方案數 這個不是很好求嗎?...
遞推 CQOI2015 選數
這個遞推實在是讓我感到無奈 實際上就是先計算出在l和r的區間中有多少個數有因數k 然後 f i 表示的就是在l和r中選出n個數最大公因數是i k 的方案數 然後 ll ll n l 1 i 1 ll rr n r i ll len rr ll 1 這幾句話的意思就是算出在n l 和 n r的範圍內有...