【数论】YY的GCD(P2257)
正題
P2257
題目大意
給你T組詢問,每組詢問給出n,m,讓你求 1≤x≤n,1≤y≤m1\leq x\leq n,1\leq y\leq m1≤x≤n,1≤y≤m 且 gcd(x,y)=primegcd(x,y)=primegcd(x,y)=prime 的方案數
解題思路
根據題意,有
∑i=1n∑j=1m[gcd(i,j)=prime]\sum_{i=1}^n\sum_{j=1}^m[gcd(i,j)=prime] i=1∑n?j=1∑m?[gcd(i,j)=prime]
考慮把prime拿出來枚舉
∑p∈primen∑i=1n/p∑j=1m/p[gcd(i,j)=1]∑p∈primen∑i=1n/p∑j=1m/p∑d∣i,d∣jμ(d)∑p∈primemin(n,m)∑d=1min(n,m)/pμ(d)×?ndp?×?mdp?\sum_{p\in prime}^n\sum_{i=1}^{n/p}\sum_{j=1}^{m/p}[gcd(i,j)=1]\\ \sum_{p\in prime}^n\sum_{i=1}^{n/p}\sum_{j=1}^{m/p}\sum_{d|i,d|j}\mu(d)\\ \sum_{p\in prime}^{min(n,m)}\sum_{d=1}^{min(n,m)/p}\mu(d)\times\left\lfloor\frac{n}{dp}\right\rfloor\times\left\lfloor\frac{m}{dp}\right\rfloor\\ p∈prime∑n?i=1∑n/p?j=1∑m/p?[gcd(i,j)=1]p∈prime∑n?i=1∑n/p?j=1∑m/p?d∣i,d∣j∑?μ(d)p∈prime∑min(n,m)?d=1∑min(n,m)/p?μ(d)×?dpn??×?dpm??
然后可以考慮改變枚舉變量
可以發現后面的兩個整除都與dp有關,那么考慮枚舉dp,那么有
∑k=1min(n,m)∑p∈prime,p∣kμ(kp)×?nk?×?mk?∑k=1min(n,m)?nk??mk?∑p∈prime,p∣kμ(kp)\sum_{k=1}^{min(n,m)}\sum_{p\in prime,p|k}\mu(\frac{k}{p})\times\left\lfloor\frac{n}{k}\right\rfloor\times\left\lfloor\frac{m}{k}\right\rfloor\\ \sum_{k=1}^{min(n,m)}\left\lfloor\frac{n}{k}\right\rfloor\left\lfloor\frac{m}{k}\right\rfloor\sum_{p\in prime,p|k}\mu(\frac{k}{p})\\ k=1∑min(n,m)?p∈prime,p∣k∑?μ(pk?)×?kn??×?km??k=1∑min(n,m)??kn???km??p∈prime,p∣k∑?μ(pk?)
對于后面的∑p∈prime,p∣kμ(kp)\sum_{p\in prime,p|k}\mu(\frac{k}{p})∑p∈prime,p∣k?μ(pk?),可以預處理,先枚舉質數,然后枚舉倍數,然后計算貢獻
對于前面的一段再整除分塊就好了
時間復雜度 O(Tn)O(T\sqrt{n})O(Tn?)
code
#include<cstdio> #include<cstring> #include<iostream> #include<algorithm> #define ll long long #define N 10000010 using namespace std; ll T,n,m,ans,w,p[N],g[N],mu[N],prime[N]; const ll MX=1e7; void work() {p[1]=mu[1]=1;for(ll i=2;i<=MX;++i){if(!p[i]){mu[i]=-1;prime[++w]=i;}for(ll j=1;j<=w&&i*prime[j]<=MX;++j){p[i*prime[j]]=1;if(i%prime[j]==0)break;else mu[i*prime[j]]=-mu[i];}}for(ll i=1;i<=w;++i)for(ll j=1;j*prime[i]<=MX;++j)g[j*prime[i]]+=mu[j];//對每個數提出一個質因數計算mu的貢獻for(ll i=2;i<=MX;++i)g[i]+=g[i-1];return; } int main() {scanf("%lld",&T);work();while(T--){scanf("%lld%lld",&n,&m);ans=0;for(ll l=1,r=0;l<=min(n,m);l=r+1){r=min(n/(n/l),m/(m/l));ans+=(n/l)*(m/l)*(g[r]-g[l-1]);}printf("%lld\n",ans);}return 0; }總結
以上是生活随笔為你收集整理的【数论】YY的GCD(P2257)的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: 养金钱龟的正确方法 金钱龟如何养
- 下一篇: 电脑如何配置显卡(怎么电脑显卡配置)