∑i=
lrx%
(k∗i
)=∑i
=lr(
x−(k
∗i)∗
⌊xk∗
i⌋)=
x∗(r
−l+1
)−∑i
=lr(
k∗i)
∗⌊x/
ki
⌋\displaystyle \sum^_= \displaystyle \sum^_ \rfloor)}\\=x*(r-l+1)-\displaystyle \sum^_\rfloor}
i=l∑r
x%(k
∗i)=
i=l∑
r(x
−(k∗
i)∗⌊
k∗ix
⌋)=
x∗(r
−l+1
)−i=
l∑r
(k∗i
)∗⌊i
x/k
⌋後邊∑i=
lr(k
∗i)∗
⌊x/k
i⌋
\displaystyle \sum^_\rfloor}
i=l∑r
(k∗i
)∗⌊i
x/k
⌋就是除法分塊的部分。
⌊ x/
ki
⌋\lfloor \frac\rfloor
⌊ix/k
⌋在一段連續[i]
[ i ]
[i]區間是相同的
所以我們列舉 l
ll 令:t=⌊
x/kl
⌋t=\lfloor \frac\rfloor
t=⌊lx/
k⌋
然後找到 t
tt 相同的區間右端點 r
rr:r=t
==0?
r:mi
n(x/
k/t,
r)
r= t==0 \ ? \ r \ : \ min(x/k/t, r)
r=t==0
?r:m
in(x
/k/t
,r)
這一塊的值就是:t∗k
∗(r−
l+1)
∗(r+
l)/2
t*k*(r-l+1)*(r+l)/2
t∗k∗(r
−l+1
)∗(r
+l)/
2:就是把相同的 t 和 k 提出來,後邊是連續區間 i 相加,也就是差值為1的等差序列求和。
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
using
namespace std;
typedef
long
long ll ;
ll read()
while
(c >=
'0'&& c <=
'9')
return x * f;
}const
int maxn =20;
const
int maxm =
1003
;const ll mod =
1e9+7;
ll fpow
(ll x, ll y)
return ans;
}ll l, r, x, k;
intmain()
cout << ans % mod << endl;
}return0;
}
基礎除法分塊:
p2261 [cqoi2007]餘數求和
#include
#include
#include
#include
#include
#define inf 0x3f3f3f3f
using
namespace std;
typedef
long
long ll ;
ll read()
while
(c >=
'0'&& c <=
'9')
return x * f;
}const
int maxn =20;
const
int maxm =
1003
;const ll mod =
1e9+7;
ll n, k;
intmain()
cout << ans << endl;
return0;
}
Fear Factoring 除法分塊)
借鑑 無法估計他的值時最好用無符號的long long 除法分塊 區塊值 區塊始末 舉個例子 12 次數是有12 n算出來的 像當n 5時 12 5 2,也就是說5出現了兩次 1 12次 2 6次 3 4次 4 3次 5 2次 6 2次 7 1次 8 1次 9 1次 10 1次 11 1次 12 1...
除法分塊小結
例題 求 i 1n n i sum n lfloor frac n i rfloor i 1n in o n o n o n 的做法很顯然,但是一般n會很大,於是有了除法分塊。對於一段連續的 i ii,ni lfloor dfrac n i rfloor in 可能是相同的,比如說當 i ii 的值...
除法分塊 數論
問題 當我們暴力的時候時間複雜度為o n 但是我們可以把時間複雜度降到o sqrt n 這點時間優化在數論中可是不能小視的。除法分塊 所謂分塊,就是把一段數分成不同的區間,而這些區間的每乙個數除以同乙個數的值是相同的,所以我們就把這些區間統一處理,就不用再來乙個乙個遍歷 例 問題中我們假設n 10。...