日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

[CQOI2015]选数(数论分块+杜教筛)

發布時間:2023/12/3 编程问答 31 豆豆
生活随笔 收集整理的這篇文章主要介紹了 [CQOI2015]选数(数论分块+杜教筛) 小編覺得挺不錯的,現在分享給大家,幫大家做個參考.

problem

洛谷鏈接

solution

L,HL,HL,H 的范圍放縮 1K\frac 1 KK1?,都除掉 KKK,特殊的 LLL 邊界注意一下。

H←H/K,L←(L?1)/K+1H\leftarrow H/K,L\leftarrow (L-1)/K+1HH/K,L(L?1)/K+1

問題轉化為 [L,H][L,H][L,H] 中任選 NNN 個數 gcd=1\text{gcd}=1gcd=1 的方案數。

T(i):T(i):T(i):[L,H][L,H][L,H] 中選 NNN 個數 i∣gcdi|\text{gcd}igcd 的方案數,即 (?Hi???L?1i?)N(\lfloor\frac H i\rfloor-\lfloor\frac {L-1}i\rfloor)^N(?iH????iL?1??)N

t(i):t(i):t(i):[L,H][L,H][L,H] 中選 NNN 個數 i=gcdi=\text{gcd}i=gcd 的方案數。

根據定義顯然有,T(i)=∑i∣dt(d)T(i)=\sum_{i|d}t(d)T(i)=id?t(d)

莫比烏斯反演得 t(i)=∑i∣dμ(di)T(d)t(i)=\sum_{i|d}\mu(\fracozvdkddzhkzd{i})T(d)t(i)=id?μ(id?)T(d)

答案即為 t(1)=∑i=1infμ(i)T(i)=∑i=1infμ(i)(?Hi???L?1i?)Nt(1)=\sum_{i=1}^{inf}\mu(i)T(i)=\sum_{i=1}^{inf}\mu(i)(\lfloor\frac H i\rfloor-\lfloor\frac {L-1}i\rfloor)^Nt(1)=i=1inf?μ(i)T(i)=i=1inf?μ(i)(?iH????iL?1??)N

H,LH,LH,L 非常大,不能直接線篩后整除分塊。

但可杜教篩,設定一個閥值 MMM 預處理出 MMM 以內的 μ\muμ,同樣整除分塊后杜教篩能做到 O(H23)O(H^{\frac 2 3})O(H32?)

T(i)T(i)T(i) 分類,假設 i∈[l,r]i\in[l,r]i[l,r]T(i)T(i)T(i) 都是一樣的,那么對 ∑i=lrμ(i)\sum_{i=l}^r\mu(i)i=lr?μ(i) 進行杜教篩迅速求和。

∑i=lrμ(i)=∑i=1rμ(i)?∑i=1l?1μ(i)\sum_{i=l}^r\mu(i)=\sum_{i=1}^r\mu(i)-\sum_{i=1}^{l-1}\mu(i)i=lr?μ(i)=i=1r?μ(i)?i=1l?1?μ(i)。這樣就化成了標準的杜教篩形式。

∑μ(i):?=μ?I\sum\mu(i):\epsilon=\mu*Iμ(i):?=μ?Ih??;f?μ;g?Ih\leftrightarrow \epsilon;f\leftrightarrow \mu;g\leftrightarrow Ih??;f?μ;g?I

s(n)=∑i=1nf(i)=∑i=1nμ(i)s(n)=\sum_{i=1}^nf(i)=\sum_{i=1}^n\mu(i)s(n)=i=1n?f(i)=i=1n?μ(i)

g(1)s(n)=∑i=1n?(i)?∑i=2ng(i)s(?ni?)?s(n)=1?∑i=2ns(?ni?)g(1)s(n)=\sum_{i=1}^n\epsilon(i)-\sum_{i=2}^ng(i)s(\lfloor\frac n i\rfloor)\Leftrightarrow s(n)=1-\sum_{i=2}^ns(\lfloor\frac n i\rfloor)g(1)s(n)=i=1n??(i)?i=2n?g(i)s(?in??)?s(n)=1?i=2n?s(?in??)

sss 函數進行記憶化遞歸,以及同樣的整除分塊。

這樣子連 H?L≤1e5H-L\le 1e5H?L1e5 的性質都沒有用上!^_^ 這性質好像是拿來容斥遞推用的。

一些省掉的推導?莫比烏斯反演,杜教篩。

code

#include <bits/stdc++.h> using namespace std; #define int long long #define mod 1000000007 #define maxn 1000005 int mu[maxn], prime[maxn]; bool vis[maxn]; unordered_map < int, int > mp; int N, M, K, L, H, cnt;int qkpow( int x, int y ) {int ans = 1;while( y ) {if( y & 1 ) ans = ans * x % mod;x = x * x % mod;y >>= 1;}return ans; }int solve( int n ) {if( n <= M ) return mu[n];if( mp.find( n ) != mp.end() ) return mp[n];int ans = 1;for( int l = 2, r;l <= n;l = r + 1 ) {r = n / ( n / l );( ans -= solve( n / l ) * ( r - l + 1 ) ) %= mod;}return mp[n] = ans; }signed main() {scanf( "%lld %lld %lld %lld", &N, &K, &L, &H );H /= K, L = ( L - 1 ) / K + 1;M = min( (int)1e6, H );mu[1] = 1; for( int i = 2;i <= M;i ++ ) {if( ! vis[i] ) prime[++ cnt] = i, mu[i] = -1;for( int j = 1;j <= cnt and i * prime[j] <= M;j ++ ) {vis[i * prime[j]] = 1;if( i % prime[j] == 0 ) { mu[i * prime[j]] = 0; break; }else mu[i * prime[j]] = -mu[i];}}for( int i = 1;i <= M;i ++ ) mu[i] += mu[i - 1];L --; int ans = 0;for( int l = 1, r;l <= H;l = r + 1 ) {if( ! ( L / l ) ) r = H / ( H / l );else r = min( H / ( H / l ), L / ( L / l ) );( ans += qkpow( H / l - L / l, N ) * ( solve( r ) - solve( l - 1 ) ) ) %= mod;}printf( "%lld\n", ( ans + mod ) % mod );return 0; }

總結

以上是生活随笔為你收集整理的[CQOI2015]选数(数论分块+杜教筛)的全部內容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網站內容還不錯,歡迎將生活随笔推薦給好友。