CF1342C Yet Another Counting Problem
阿新 • • 發佈:2021-09-07
考察對取模“週期性”的理解。
給定兩個數 \(a,b\),進行 \(q\) 次詢問,對於每次詢問給出回答——在 \([l,r]\) 中,滿足以下條件的 \(x\) 的個數:\((x \mod a) \mod b=(x \mod b) \mod a\) 的數的個數。保證 \(l_i,r_i\le 10^{18}\)。
什麼時候會合法呢?不難想到取模的週期性。
- 如果 \(x \mod a=y\),則 \((x+a) \mod a=y\),進而推得 \((x+a\times k) \mod a=y\)。
- 如果 \(x \mod b=y\),則 \((x+b) \mod b=y\),進而推得 \((x+b\times k) \mod b=y\)
- 如果 \((x \mod a) \mod b=(x \mod b) \mod a\),不難發現,\(((x+k\times ab) \mod a)\mod b=((x+k\times ab) \mod b)\mod a\)。
迴圈! 迴圈節是 \(a\times b\)。故此,我們只需要預處理出 \(0 \to a\times b-1\) 範圍內合法的數,就可以推到任意區間。具體公式是 \(\lceil\frac{x}{ab}\rceil \times sum_{ab-1}+sum_{x\mod ab}\)。
時間複雜度 \(O(ab+q)\)。
下面是預處理:
t=a*b; for(reg int i=0;i<t;++i){ if((i%a%b)!=(i%b%a)) s[i]=1; for(reg int i=1;i<a*b;++i) s[i]+=s[i-1]; }
下面是查詢函式:
inline LL ask(LL x){
if(x==0) return 0;
LL y=x/t,res=s[t-1]*y;
x-=y*t;
return res+s[x];
}