poj2480(求欧拉函数单值/积性函数+狄利克雷卷积)

版权声明:本文为博主原创文章,未经博主允许不得转载。 https://blog.csdn.net/qkoqhh/article/details/81917174

显然是要枚举一下gcd然后按gcd分类去求,所以原式化为\small \sum_{d|n}\sum_{i=1}^{n}[gcd(i,n)==d]=\sum_{d|n}d\varphi(\frac{n}{d})

然后枚举d需要sqrt(n),求一个φ需要logn,由于并不是每次都要求那么大的φ,所以时间上限为O(sqrt(n)logn)

然后看到网上有更快的做法。。想学一下然后看不懂证明。。

然后发现\small \sum_{d|n}d\varphi(\frac{n}{d})符合狄利克雷卷积形式(虽然还不造是什么),所以答案本身就是一个积性函数

求解积性函数,最关键的还是求解f(p^k),令答案为f(n),此时d只能为p的幂次方,有

\small f(p^k)=\sum_{d|p^k}d\varphi(\frac{p^k}{d})=\sum_{i=0}^{k}p^i\varphi(p^{k-i})=\sum_{i=0}^{k-1}(p-1)p^{k-1}+p^k=k(p-1)p^{k-1}+p^k

然后对n进行素数幂分解之后求f(n)即可

可能是道基础题。。不过对窝这种初学者来说确实是道好题。。

求欧拉函数单值:

/**
 *          ┏┓    ┏┓
 *          ┏┛┗━━━━━━━┛┗━━━┓
 *          ┃       ┃  
 *          ┃   ━    ┃
 *          ┃ >   < ┃
 *          ┃       ┃
 *          ┃... ⌒ ...  ┃
 *          ┃              ┃
 *          ┗━┓          ┏━┛
 *          ┃          ┃ Code is far away from bug with the animal protecting          
 *          ┃          ┃   神兽保佑,代码无bug
 *          ┃          ┃           
 *          ┃          ┃        
 *          ┃          ┃
 *          ┃          ┃           
 *          ┃          ┗━━━┓
 *          ┃              ┣┓
 *          ┃              ┏┛
 *          ┗┓┓┏━━━━━━━━┳┓┏┛
 *           ┃┫┫       ┃┫┫
 *           ┗┻┛       ┗┻┛
 */
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<bitset>
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge *j=h[x];j;j=j->next)
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
#define eps 1e-8
#define succ(x) (1LL<<(x))
#define lowbit(x) (x&(-x))
#define sqr(x) ((x)*(x))
#define mid (x+y>>1)
#define NM 3000005
#define nm 220005
#define N 40005
#define M(x,y) x=max(x,y)
const double pi=acos(-1);
const ll inf=1e16;
using namespace std;
ll read(){
    ll x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}


ll n;
ll ans;

ll ph(ll n){
    ll s=n;
    for(ll i=2;i*i<=n;i++)if(n%i==0){
	s-=s/i;while(n%i==0)n/=i;
    }
    if(n>1)s-=s/n;return s;
}

int main(){
    while(~scanf("%lld",&n)){
	ans=0;
	for(ll i=1;i*i<=n;i++)if(n%i==0){
	    ans+=i*ph(n/i);
	    if(sqr(i)!=n)ans+=n/i*ph(i);
	}
	printf("%lld\n",ans);
    }
    return 0;
}

积性函数:

/**
 *          ┏┓    ┏┓
 *          ┏┛┗━━━━━━━┛┗━━━┓
 *          ┃       ┃  
 *          ┃   ━    ┃
 *          ┃ >   < ┃
 *          ┃       ┃
 *          ┃... ⌒ ...  ┃
 *          ┃              ┃
 *          ┗━┓          ┏━┛
 *          ┃          ┃ Code is far away from bug with the animal protecting          
 *          ┃          ┃   神兽保佑,代码无bug
 *          ┃          ┃           
 *          ┃          ┃        
 *          ┃          ┃
 *          ┃          ┃           
 *          ┃          ┗━━━┓
 *          ┃              ┣┓
 *          ┃              ┏┛
 *          ┗┓┓┏━━━━━━━━┳┓┏┛
 *           ┃┫┫       ┃┫┫
 *           ┗┻┛       ┗┻┛
 */
#include<cstdio>
#include<cstring>
#include<algorithm>
#include<iostream>
#include<queue>
#include<cmath>
#include<map>
#include<stack>
#include<set>
#include<bitset>
#define inc(i,l,r) for(int i=l;i<=r;i++)
#define dec(i,l,r) for(int i=l;i>=r;i--)
#define link(x) for(edge *j=h[x];j;j=j->next)
#define mem(a) memset(a,0,sizeof(a))
#define ll long long
#define eps 1e-8
#define succ(x) (1LL<<(x))
#define lowbit(x) (x&(-x))
#define sqr(x) ((x)*(x))
#define mid (x+y>>1)
#define NM 500005
#define nm 1000005
#define N 1000005
#define M(x,y) x=max(x,y)
const double pi=acos(-1);
const int inf=20170817;
using namespace std;
ll read(){
    ll x=0,f=1;char ch=getchar();
    while(!isdigit(ch)){if(ch=='-')f=-1;ch=getchar();}
    while(isdigit(ch))x=x*10+ch-'0',ch=getchar();
    return f*x;
}
  
 

ll n;

ll solve(ll n){
    ll s=1;
    for(ll i=2;i*i<=n;i++)if(n%i==0){
	int k=0,t=1;
	while(n%i==0)n/=i,k++,t*=i;
	s*=k*(i-1)*t/i+t;
    }
    if(n)s*=n-1+n;return s;
}

int main(){
    while(~scanf("%lld",&n))printf("%lld\n",solve(n));
}

Longge's problem

Time Limit: 1000MS   Memory Limit: 65536K
Total Submissions: 9865   Accepted: 3283

Description

Longge is good at mathematics and he likes to think about hard mathematical problems which will be solved by some graceful algorithms. Now a problem comes: Given an integer N(1 < N < 2^31),you are to calculate ∑gcd(i, N) 1<=i <=N.

"Oh, I know, I know!" Longge shouts! But do you know? Please solve it.

Input

Input contain several test case.
A number N per line.

Output

For each N, output ,∑gcd(i, N) 1<=i <=N, a line

Sample Input

2
6

Sample Output

3
15

Source

POJ Contest,Author:Mathematica@ZSU

[Submit]   [Go Back]   [Status]   [Discuss]

猜你喜欢

转载自blog.csdn.net/qkoqhh/article/details/81917174