フェイス質問
https://www.luogu.com.cn/problem/P1587
問題の解決策
事前知識
すべての質問が尋ね(1 {\当量}、X \ {\}当量のN、1 {\当量} Y {\当量} M \) に形成され\({\ FRAC {X} {Y}} \) K進異なる純粋で小数点以下の桁数。(整数とみなすことができます)
被験者の解析、変換条件:純粋な循環小数と等価\((Y、K)= 1 \。) ;及び全ての重複する値(\ {\ FRAC {X} {Y}} \) 順番には、取ることができる((\ X、Y)= 1 \)代表として、あまり良好統計こと。
追求するので、同等
\ [{\和\ limits_ {Y = 1} ^ {M}} {\和\ limits_ {X = 1} ^ {N}} [(Y、K)= 1] [(X、Y)= 1] \]
\ [= {\和\ limits_ {Y = 1} ^ {M}} [(Y、K)= 1] {\和\ limits_ {X = 1} ^ {N}} {\和\ limits_ {D | X、D | Y}} {\ MU(D)} \]
\ [= {\和\ limits_ {Y = 1} ^ {M}} [(Y、K)= 1] {\和\ limits_ {D | Y} ^ {1 {\当量} D {\当量}分(N、M)}} {\ MU(D)} {\ lfloor} {\ FRAC {n}は{D}} {\ rfloor} \]
\ [= {\和\限界_ {(D、K)= 1} ^ {1 {\当量} D {\当量}分(N、M)}} {\ MU(D)} {\ lfloor} {\ FRAC {n}は{D}} {\ rfloor} {\和\ limits_ {Y '= 1} ^ {{\ lfloor} {\ FRAC {M} {D}} {\ rfloor}}} [(Y'、 K)= 1] \]
\({\ MU(D) } \) 既にブロック番号理論によって処理何か後ろ。\({\ sum_ {Y ' = 1} ^ {{\ lfloor} {\ FRAC {M} {D}} {\ rfloor}}} [(Y'、K)= 1] \) この部分、意味〜1 \({\ lfloor} {\ FRAC D {M}}}、{{\ rfloor} \)番号k素数と\(F({\ lfloor} {\ FRAC {M} {D {}} \ rfloor})\)。小さなkに、我々は、前処理されてもよい\(F(1)\)に\(F(K)\) 、次いで(\ {\ lfloor} {\ FRAC {M} {D}} {\ rfloor} \) 残りのk及びkで割った整数倍数の後、我々はでき(O(1)\)\アドレスこの部分。
残りのものは、解決する方法である(\ {\ SUMは_ {(D、K)= 1} ^ {1 {\のLeq} D {\のLeq} R} {\ MU(D)を} \) R理論です、ブロックの右端の後。
二つの画面がDUが全て解決する教えることができるように、m個のR割り切れる特定のセットの全てにおいて見出さ又はn \(合計\ MU(R) = {\ sum_ {1 {\当量} D {\当量} R}を{} \ MU(D)} \) 。問題は、今も\((D、K)= 1 \) 条件。
我々は考える\({\和_ {( D、K){\ NEQ} 1} ^ {1 {\当量} D {\当量} R} {\ MU(d)は} \) です。次に、検索するための驚き:起因する小さなkに、そう満足するよう\((D、K){\ NEQ} 1 \。)だけでなく、満たすために、({\ MU(D)\ {\ NEQ} 0} \) 実際にはない数たくさん。
\(DT(R)\)これを記述すると。上記の条件を満足する行を考えるDおよびK、K-GCD一部のみ素因数をGCD、各周波数は、1個以下にすることはできません。しかしながら、\({K \}のLeq 2000 \) 、その結果、4 K素因数の唯一最大。だから、これは15までGCD。その後、関係が描かれることができます:
\ [DT(N)= {\和\ limits_ {GCD}} {\} {\和\限界_ {(D、K)= 1} ^ {1 {\当量} D {\当量} {\ FRAC {K } {GCD}}}} {\ MU(D)} \]
\ [= {\和\ limits_ {GCD}} {\ MU(GCD)}(合計\ MU({\ FRAC {K} {GCD}}) - DT(\ FRAC {K} {GCD}))\]
全てDTまたは添字後に表示されるn個のすべてのDTの合計の計算の複雑さがあるので、セット内の数mで割り切れる\(O(({\ SQRT {N}} + \ SQRT {M}))w \) 、ここで、wは、この問題では、異なるGCDの数であり、{\}のLeq 15 \)W(\。
要約すると、この質問の合計時間複雑である\(O(\ SQRT {W} + N-N- ^ {\ FRAC。3} {2} {})\) 。
- 様々なアプローチがあります。この問題は、他のアプローチが見https://www.luogu.com.cn/problemnew/solution/P1587を
コード
#include<bits/stdc++.h>
using namespace std;
#define ll long long
#define rg register
#define K 2000
#define T 1000000
ll n,m,k,pn;
ll pri[T+5],smu[T+5];
bool isp[T+5];
inline void Eular(){
smu[1] = 1;
for(rg ll i = 2;i <= T;i++)isp[i] = 1;
for(rg ll i = 2;i <= T;i++){
if(isp[i])pri[++pn] = i,smu[i] = -1;
for(rg ll j = 1;i * pri[j] <= T;j++){
isp[i*pri[j]] = 0;
if(i % pri[j])smu[i*pri[j]] = -smu[i];
else{
smu[i*pri[j]] = 0;
break;
}
}
}
for(rg ll i = 2;i <= T;i++)smu[i] += smu[i-1];
}
ll f[K+5]; //f[i]表示1~i中与k互质的数的个数
inline ll gcd(ll a,ll b){
return b ? gcd(b,a % b) : a;
}
inline ll calc(ll n){ //计算1~i中与k互质的数的个数
return (n / k) * f[k] + f[n%k];
}
unordered_map<ll,ll>Hash;
inline ll summu(int n){ //杜教筛
if(n <= T)return smu[n];
if(Hash.count(n))return Hash[n];
ll ans = 1;
int L,R = 1;
while(R < n){
L = R + 1,R = n / (n / L);
ans -= 1ll * (R - L + 1) * summu(n / L);
}
return Hash[n] = ans;
}
vector<ll>fac;
ll fn,fc[16+5]; //所有k的mu值不等于0的约数(除了1)
inline void divide(ll n){ //分解k
for(rg ll i = 1;i <= pn;i++){
if(n % pri[i] == 0){
fac.push_back(pri[i]);
while(n % pri[i] == 0)n /= pri[i];
}
if(n == 1)break;
}
}
unordered_map<ll,ll>Dt;
inline ll dt(int n){ //1~n中与k互质的数的\mu值之和
if(!n)return 0;
if(Dt.count(n))return Dt[n];
ll ans = 0;
for(rg ll i = 1;i <= fn;i++)ans += (smu[fc[i]] - smu[fc[i]-1]) * (summu(n/fc[i]) - dt(n/fc[i]));
return Dt[n] = ans;
}
int main(){
cin >> n >> m >> k;
Eular();
divide(k);
for(rg ll mask = 1;mask < 1ll << fac.size();mask++){
ll cur = 1;
for(rg ll i = 0;i < fac.size();i++)
if((bool)(mask & (1ll << i)))cur *= fac[i];
fc[++fn] = cur;
}
for(rg ll i = 1;i <= k;i++)f[i] = f[i-1] + (gcd(i,k) == 1);
ll ans = 0;
int L,R = 0,limit = min(n,m);
while(R < limit){
L = R + 1,R = min(n / (n/L),m / (m/L));
ans += ((summu(R)-dt(R)) - (summu(L-1)-dt(L-1))) * (n / L) * calc(m / L);
}
cout << ans << endl;
return 0;
}