[HDU1695]GCD + [HAOI2011]Problem b + [POI2007]ZAP-Queries【莫比烏斯反演】
阿新 • • 發佈:2018-07-11
最終 floor line cas pri int += problem cpp
\[g(x)=\sum_{x|d}f(d)\]
\[=\sum_{i=1}^{\lfloor\frac{n}{k}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{k}\rfloor}[x|GCD(i, j)]\]
\[=\sum_{i=1}^{\lfloor\frac{n}{xk}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{xk}\rfloor}[1|GCD(i, j)]\]
\[=\lfloor\frac{n}{xk}\rfloor\lfloor\frac{m}{xk}\rfloor\]
\[f(n)=\sum_{n|d}\mu(\frac{d}{n})g(d)\]
則\[ans(n, m)=f(1)=\sum_{d=1}^n\mu(d)g(d)\]
\[=\sum_{d=1}^n\mu(d)\lfloor\frac{n}{dk}\rfloor\lfloor\frac{m}{dk}\rfloor\]
[HDU1695]GCD
[HAOI2011]Problem b
[POI2007]ZAP-Queries
令\[ans(n, m)=\sum_{i=1}^n\sum_{j=1}^m[GCD(i, j) == k]\]
\[=\sum_{i=1}^{\lfloor\frac{n}{k}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{k}\rfloor}[GCD(i, j) == 1]\]
令\[f(d)=\sum_{i=1}^{\lfloor\frac{n}{k}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{k}\rfloor}[GCD(i, j) == d]\]
\[g(x)=\sum_{x|d}f(d)\]
\[=\sum_{i=1}^{\lfloor\frac{n}{k}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{k}\rfloor}[x|GCD(i, j)]\]
\[=\sum_{i=1}^{\lfloor\frac{n}{xk}\rfloor}\sum_{j=1}^{\lfloor\frac{m}{xk}\rfloor}[1|GCD(i, j)]\]
\[=\lfloor\frac{n}{xk}\rfloor\lfloor\frac{m}{xk}\rfloor\]
\[f(n)=\sum_{n|d}\mu(\frac{d}{n})g(d)\]
則\[ans(n, m)=f(1)=\sum_{d=1}^n\mu(d)g(d)\]
\[=\sum_{d=1}^n\mu(d)\lfloor\frac{n}{dk}\rfloor\lfloor\frac{m}{dk}\rfloor\]
[HDU1695]GCD
又\((x, y)\)和\((y,x)\)是等價的,要減去重復算的
假設\(b<d\),則最終\(ans=ans(b, d)-ans(b, b)/2\)
void init(){ miu[1]=1; for(int i=2; i < N; i++) { if(!p[i]) p[++p[0]]=i, miu[i]=-1; for(int j=1; j <= p[0] && i*p[j] < N; j++){ p[i*p[j]]=1; if(i%p[j] == 0) {miu[i*p[j]]=0; break;} else miu[i*p[j]]=-miu[i]; } } } void solve(){ init(); int T=read(); for(int i=1; i <= T; i++){ int a=read(), b=read(), c=read(), d=read(), k=read(); cout<<"Case "<<i<<": "; if(k == 0) {cout<<0<<endl; continue;} b/=k, d/=k; ll ans1=0, ans2=0, mn=min(b, d); for(int i=1; i <= mn; i++) ans1+=1LL*miu[i]*(b/i)*(d/i), ans2+=1LL*miu[i]*(mn/i)*(mn/i); cout<<ans1-ans2/2<<endl; } }
[HAOI2011]Problem b
這題要容斥一下\(ans=ans(b, d)-ans(a-1, d)-ans(b, c-1)+ans(a-1, c-1)\),
還要整除分塊,否則會\(TLE\)
void init(){
p[1]=miu[1]=1;
for(int i=2; i < N; i++) {
if(!p[i]) p[++p[0]]=i, miu[i]=-1;
for(int j=1, x; j <= p[0] && (x=p[j]*i) < N; j++){ p[x]=1;
if(i%p[j] == 0) {miu[x]=0; break;} miu[x]=-miu[i];
}
}
for(int i=1; i < N; i++) miu[i]+=miu[i-1];
}
ll cal(ll m, ll n){ m/=k, n/=k;
ll ans=0, mn=min(n, m);
for(int i=1, j; i <= mn; i=j+1){
j=min(n/(n/i), m/(m/i));
ans+=1LL*(miu[j]-miu[i-1])*(n/i)*(m/i);
}
return ans;
}
void solve(){
int T=read(); init();
while(T--){
ll a=read(), b=read(), c=read(), d=read(); k=read();
printf("%lld\n", cal(b, d)-cal(a-1, d)-cal(b, c-1)+cal(a-1, c-1));
}
}
[POI2007]ZAP-Queries 這題\(ans=ans(n, m)\)
[HDU1695]GCD + [HAOI2011]Problem b + [POI2007]ZAP-Queries【莫比烏斯反演】