bzoj 2818 Gcd(莫比烏斯+gcd(a,b)=d) 經典
2818: Gcd
Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1566
Description
給定整數N,求1<=x,y<=N且Gcd(x,y)為素數的
數對(x,y)有多少對.
Input
一個整數N
Output
如題
Sample Input
4Sample Output
4HINT
hint
對於樣例(2,2),(2,4),(3,3),(4,2)
1<=N<=10^7
題意:給一個正整數 N,其中1<=N<=10^7,求使得 gcd(x,y)為質數的
(x,y)對的個數,1<=x,y<=n
分析:莫比烏斯反演,十分的巧妙。
GCD(a,b)的題十分經典。GCD(a,b)=d (d是素數),但是思想卻是相同的。
設f(d) = GCD(a,b) = d的種類數 ;
F(n) 為GCD(a,b) = d 的倍數的種類數,GCD(a,b)%d==0;
即 :F(x) = (N/x)*(N/x);//N中是x的倍數的個數,然後組合
則f(x) = sigma( mu[d/x]*F(d), d|n )
由於d = 1 所以f(1) = sigma( mu[d]*F(p*d) ) = sigma( mu[d]*(N/pd)*(N/pd) ); p為列舉的素數;p*d<N; (優化!否則會超時)
so....
初探莫比烏斯。還有很多不是很懂。跟進中。。。
#include<cstdio> #include<cstring> #include<algorithm> using namespace std; const int MAXN = 1e7+10; typedef long long LL; //LL F[MAXN],f[MAXN]; LL pri[MAXN],pri_num; LL mu[MAXN];//莫比烏斯函式值 bool vis[MAXN]; void mobius(int N) //篩法求莫比烏斯函式 { pri_num = 0;//素數個數 memset(vis, false, sizeof(vis)); vis[1] = true; mu[1] = 1; for(int i = 2; i <=N; i++) { if(!vis[i]) { pri[pri_num++] = i; mu[i] = -1; } for(int j=0; j<pri_num && i*pri[j]<N ; j++) { vis[i*pri[j]]=true;//標記非素數 //eg:i=3,i%2,mu[3*2]=-mu[3]=1;----;i=6,i%5,mu[6*5]=-mu[6]=-1; if(i%pri[j])mu[i*pri[j]] = -mu[i]; else { mu[i*pri[j]] = 0; break; } } } } int main() { // freopen("in.txt","r",stdin); // freopen("out.txt","w",stdout); LL n; mobius(10000000); while(~scanf("%lld",&n)) { LL ans = (LL)0; for(LL i=0; pri[i]<=n; i++) { for(LL j=1; j<=n/pri[i]; j++) ans+=(LL)(mu[j]*((n/pri[i])/j)*((n/pri[i])/j)); } printf("%lld\n",ans); } return 0; }
我的程式碼跑了7秒。。。學長的程式碼跑了6秒。。。僅供參考
/* Language: C++
Result: Accepted
Time:6432 ms
Memory:167288 kb
****************************************************************/
#include<iostream>
#include<stdio.h>
#include<cstring>
#include<cstdlib>
using namespace std;
typedef long long LL;
const int maxn = 1e7+1;
bool s[maxn];
int prime[maxn],len = 0;
int mu[maxn];
int g[maxn];
int sum1[maxn];
void init()
{
memset(s,true,sizeof(s));
mu[1] = 1;
for(int i=2; i<maxn; i++)
{
if(s[i] == true)
{
prime[++len] = i;
mu[i] = -1;
g[i] = 1;
}
for(int j=1; j<=len && (long long)prime[j]*i<maxn; j++)
{
s[i*prime[j]] = false;
if(i%prime[j]!=0)
{
mu[i*prime[j]] = -mu[i];
g[i*prime[j]] = mu[i] - g[i];
}
else
{
mu[i*prime[j]] = 0;
g[i*prime[j]] = mu[i];
break;
}
}
}
for(int i=1; i<maxn; i++)
sum1[i] = sum1[i-1]+g[i];
}
int main()
{
int a;
init();
while(scanf("%d",&a)>0)
{
LL sum = 0;
for(int i=1,la = 0 ; i<=a; i = la+1)
{
la = a/(a/i);
sum = sum + (long long)(sum1[la] - sum1[i-1])*(a/i)*(a/i);
}
printf("%lld\n",sum);
}
return 0;
}
網上有其他的解法。。。還快些(5秒)
/**************************************************************
Problem: 2818
Language: C++
Result: Accepted
Time:5220 ms
Memory:128224 kb
****************************************************************/
#include<bits/stdc++.h>
#define clr(a,x) memset(a,x,sizeof(a))
#define rep(i,l,r) for(int i=l;i<r;i++)
typedef long long ll;
using namespace std;
// 尤拉函式
int read()
{
char c=getchar();
int ans=0,f=1;
while(!isdigit(c)){
if(c=='-') f=-1;
c=getchar();
}
while(isdigit(c)){
ans=ans*10+c-'0';
c=getchar();
}
return ans*f;
}
const int maxn=10000009;
bool p[maxn];
ll f[maxn];
int s[maxn],cnt,n;
void getphi()
{
rep(i,1,n+1) f[i]=i;
rep(i,2,n+1){
if(f[i]==i){
for(int j=i;j<=n;j+=i){
f[j]=f[j]/i*(i-1);
}
}
}
rep(i,2,n+1) f[i]+=f[i-1];
}
void getsushu()
{
clr(p,-1);
p[1]=0;
rep(i,2,(n>>1)+1){
if(p[i]){
for(int j=i<<1;j<=n;j+=i){
p[j]=0;
}
}
}
rep(i,2,n+1){
if(p[i]){
s[cnt++]=i;
}
}
}
int main()
{
n=read();
getphi();
getsushu();
ll ans=0;
rep(i,0,cnt){
ans+=f[n/s[i]]*2-1;
}
printf("%lld\n",ans);
return 0;
}
mada...mada...!!!
相關推薦
bzoj 2818 Gcd(莫比烏斯+gcd(a,b)=d) 經典
2818: Gcd Time Limit: 10 Sec Memory Limit: 256 MBSubmit: 1566 Description 給定整數N,求1<=x,y&l
BZOJ 2820 YY的GCD 莫比烏斯反演
cstring std swap cst pac lap Go hint name 2820: YY的GCD Description 神犇YY虐完數論後給傻×kAc出了一題給定N, M,求1<=x<=N, 1<=y<=
BZOJ 2820: YY的GCD [莫比烏斯反演]
題解: 和上一題相同的函式: 為滿足且和的的對數 為滿足且和的的對數 顯然,反演後得到 可以列舉每一個質數,套用上一題的做法,p相當於k,d*p也就是p的倍數了...很像上一題我WT1中的式子 其實d只要列舉到min(
Gcd HYSBZ - 2818 (莫比烏斯反演)
Gcd HYSBZ - 2818 給定整數N,求1<=x,y<=N且Gcd(x,y)為素數的 數對(x,y)有多少對. Input 一個整數N Output 如題 Sample Input 4 Sample O
BZOJ 2820 YY的GCD 莫比烏斯反演
由於這道題比較鬼畜,而且公式巨難打出,所以我粘了兩頁PoPoQQQ的PPT orz,並對其中一些部分解釋一下 最下面的公式就是換了一種列舉的方式,其中u括號裡的東西就是把d變成T/p,其中p|T的
【bzoj2820】YY的GCD 莫比烏斯反演
spa tex 給定 void fin include ans iostream while YY的GCD Description 神犇YY虐完數論後給傻×kAc出了一題 給定N, M,求1<=x<=N, 1<=y<=M且g
luogu2257 YY的GCD——莫比烏斯反演
注意一下處理字首和的時候的trick #include <bits/stdc++.h> using namespace std; #define N 10000005 bool vis[N
YY的gcd[莫比烏斯反演模板題]
YY的gcd啊,,題意如下; 多組資料 每組資料給出n,m,k; 求1<=i<=n,1<=j<=m,gcd(i,j)=k;的對數。 資料數最高為10000,n,m<=10000000 毒瘤資料。 根據上文所說,莫比烏斯反演最重要的第一步是找準
hdu1695-GCD-莫比烏斯反演入門
這裡F(X)為挑選數目為有多少對滿足 gcd(x,y)==e的倍數gcd(x,y)==e的倍數。 並且 F(x)滿足第二張圖片 (即F(n)為gcd為n的倍數的對數,這個答案等於所有f(d)
hdu GCD(莫比烏斯反演+一點學習筆記)
GCD Time Limit: 6000/3000 MS (Java/Others) Memory Limit: 32768/32768 K (Java/Others) Total Submission(s): 15999 &n
HihoCoder - 1867: GCD (莫比烏斯容斥)
rip air mut sat ins isf contains push hoc Sample Input 6 1 6 2 5 3 4 Sample Output 10 You are given a {1, 2, ..., n}-permutation a
luogu2658 GCD(莫比烏斯反演/歐拉函數)
for 初始化 urn 發現 sin org turn 素數 cst link 給定整數N,求1<=x,y<=N且Gcd(x,y)為素數的數對(x,y)有多少對. 1<=N<=10^7 (1)莫比烏斯反演法 發現就是YY的GCD,左轉YY的GCD粘過
luogu2257 YY的GCD--莫比烏斯反演
初始 lin lld cti cst scanf ret href show link 給定N, M,求1<=x<=N, 1<=y<=M且gcd(x, y)為質數的(x, y)有多少對 多組數據T = 10000 N, M <= 1000000
bzoj 1101 Zap —— 莫比烏斯反演
div spa targe ini bsp cstring bool con blank 題目:https://www.lydsy.com/JudgeOnline/problem.php?id=1101 直接莫比烏斯反演。 代碼如下: #include<cstdio
BZOJ 2818 GCD 【歐拉函數 || 莫比烏斯反演】
true names namespace sin () 莫比烏斯反演 lse tps lin 傳送門:https://www.lydsy.com/JudgeOnline/problem.php?id=2818 2818: Gcd Time Limit: 10 Sec M
BZOJ 2818 Gcd(gcd(x,y)為素數/尤拉函式/莫比烏斯反演)
題目連結: BZOJ 2818 Gcd 題意: x∈[1,N],y∈[1,N],gcd(x,y)=素數的有序對(x,y)的對數。 分析: 對於一個素數p,如果gcd(x,y)=p,那麼相當於x
莫比烏斯反演入門 HDOJ 1695:GCD 、BZOJ 2301: [HAOI2011]Problem b
下面我所說的都基於上面這篇部落格的內容。 莫比烏斯反演有兩種形式(mu表示莫比烏斯函式): HDOJ1695 GCD 求1<=x<=n,1<=y<=m中gcd(x,y)==k的(x,y)組數,注意(a,b)和(b,a)視為同一情況。 相當於計算
CO-PRIME(初探 莫比烏斯)NYOJ1066(經典)gcd(a,b)=1
put size 兩個 test hat ott == clas otto CO-PRIME 時間限制:1000 ms | 內存限制:65535 KB 難度:3 描寫敘述 This problem is so easy! Can you solve it
SPOJ - PGCD Primes in GCD Table(莫比烏斯反演)
cnblogs -s def problems 前綴和 ret mage () eof http://www.spoj.com/problems/PGCD/en/ 題意: 給出a,b區間,求該區間內滿足gcd(x,y)=質數的個數。 思路: 設f(n)為 gc
hdu 1695 GCD(莫比烏斯入門)
技術分享 sin urn cas str 由於 ons pre () 題意:求a<=x<=b ,x<=y<=d,中gcd(x,y)==k的數對個數 思路:題目可以轉化成求1<=x<=b/k,1<=y<=d/k中gcd(x,y)