【数据规模和约定】 对于 100% 的数据,1 ≤ N ≤ 40000
题解:典型的容斥题,但是看了网上的有人推出用欧拉也能做,还有用莫比乌斯函数做的。。。脑洞大开;莫比乌斯看不懂,欧拉容斥做了一遍,算是复习一下吧;由于是N*N所以可以用欧拉,最后是answer*2+1,这个他们说是看出来的。。。。。还是容斥可靠;
容斥:
1 #include<iostream>
2 #include<cstdio>
3 #include<cmath>
4 #include<algorithm>
5 #include<cstring>
6 #include<vector>
7 using namespace std;
8 typedef long long LL;
9 vector<int>p;
10 void getp(int x){
11 p.clear();
12 for(int i=2;i*i<=x;i++){
13 if(x%i==0){
14 p.push_back(i);
15 while(x%i==0){
16 x/=i;
17 }
18 }
19 }
20 if(x>1)p.push_back(x);
21 }
22 int getn(int x,LL n){
23 LL sum=0;
24 getp(x);
25 for(int i=1;i<(1<<p.size());i++){
26 LL temp=1,cnt=0;
27 for(int j=0;j<p.size();j++){
28 if(i&(1<<j)){
29 temp*=p[j];cnt++;
30 // printf("%d*",p[j]);
31 }
32 }
33 // printf("\n");
34 if(cnt&1)sum+=n/temp;
35 else sum-=n/temp;
36 }
37 return n-sum;
38 }
39 int main(){
40 LL N;
41 while(~scanf("%lld",&N)){
42 N--;
43 LL ans=0;
44 // getn(48,100)
45 for(int i=1;i<=N;i++){
46 ans+=getn(i,N);
47 // printf("%lld\n",getn(i,N));
48 }
49 printf("%lld\n",ans+2);
50 }
51 return 0;
52 }
ouler:
LL ouler(LL n){
LL p=n;
for(int i=2;i*i<=n;i++){
if(n%i==0){
p=p*(i-1)/i;
while(n%i==0)n/=i;
}
}
if(n>1)p=p*(n-1)/n;
// printf("%lld\n",p);
return p;
}
int main(){
LL N;
while(~scanf("%lld",&N)){
LL ans=0;
for(int i=1;i<N;i++){
ans+=ouler(i);
}
printf("%lld\n",ans*2+1);
}
return 0;
}
欧拉打表:
const int MAXN=500005;
LL dp[MAXN];
void db(){
dp[1]=1;
for(int i=2;i<MAXN;i++){
if(!dp[i]){
for(int j=i;j<MAXN;j+=i){
if(!dp[j])dp[j]=j;
// dp[j]=dp[j]*(i-1)/i;
}
}
dp[i]+=dp[i-1];
}
}
int main(){
db();
LL N;
while(~scanf("%lld",&N)){
printf("%lld\n",2*dp[N-1]+1);
}
return 0;
}