題意是給出n個m的約數,問[0,m-1]中至少被其中乙個約數整除的整數和。(n<=10000,m<=1000000000)
直接容斥的話,是2^n再拖個log的複雜度,加上當前的數大於m時直接跳出了剪枝,或許會小一點。
但是有乙個很重要的性質:我們容斥中所有計算過貢獻的數,都是m的因數。換言之,我們計算貢獻的數的個數是及其有限的,故可以計算出所有因數貢獻的係數。
我們給所有因數賦予互不重疊的「貢獻」,定義為所有能被其整除但不能被其他大於它的因數整除的數的和。這種貢獻是我們用來表示答案的組成的,但是不可以直接計算。
於是一開始,我們把所有是這n個約數的倍數的貢獻設為1。事實上,容斥就體現在這裡。我們這裡是設為1,而不是加1。即對於乙個同時是多個因數的倍數的數,我們只計算一次貢獻。
然而,我們在實際計算中,乙個數的貢獻在它的所有因數中都計算過了。設因數i的實際係數是ri,初始定義的係數是vi,那麼,我們有
時間複雜度o(√m+n*d(m)+d(m)^2)。(好像非常玄學)
1 #include 2小結:在容斥物件數量少的時候,存下其中的每乙個貢獻的係數是可取的優化方向。using
namespace
std;
3const
int n = 10010
;4 typedef long
long
ll;5
ll ans;
6int
a[n],n,m,p,fac[n],num[n],cnt,tmp;
7int
main()
19 sort(fac+1,fac+cnt+1
);20
for (int i = 1 ; i <= n ; ++i)
26for (int i = 1 ; i <= cnt ; ++ i) if
(num[i])
32 printf("
case #%d: %lld\n
",ca,ans);33}
34return0;
35 }
HDU 4352做題筆記
聽說是多校的題,難怪做自閉了 參考了網上各種題解終於大概懂了,這裡放幾個我參考的 i.ii.iii.首先本題要求l到r範圍內,在2進製下,lis長度為k的數的個數,於是想到數字dp,那麼怎麼處理lis呢,以及如何記錄狀態呢 首先看到l和r的大小,要求乙個數的lis,通常想法是把這個數存下來。但是由於...
HDU 2016 11 12 做題感想
細數一下這兩天做過的值得總結的一些題orz.hdu 2571 簡單dp,但是一開始wa了一發。原因很簡單 沒有考慮仔細。如果指向該點的所有點權值都為負數,那就錯了 我一開始預設初始值為0 這是非常基礎的典型dag模型,好久不做,手明顯生了 1 include 2 3using namespace s...
hdu4267線段樹段更新,點查詢,55棵線段樹
題意 給你n個數,q組操作,操作有兩種,查詢和改變,查詢就是查詢當前的這個數上有多少,更改是給你a b k c,每次從a到b,每隔k的數更改一次,之間的數不更改,就相當於跳著更新.思路 別人的 i a k 0 等價於 i k a k 一共有10中情況 還有列舉所有情況中的小情況 1 1 2 3 4 ...