码迷,mamicode.com
首页 > 其他好文 > 详细

bzoj 2190: [SDOI2008]仪仗队

时间:2018-02-02 23:20:28      阅读:211      评论:0      收藏:0      [点我收藏+]

标签:std   max   return   class   ref   技术分享   分享图片   stream   src   

bzoj 2190

技术分享图片

显然

以C菌为原点构建坐标系

当横纵坐标(a,b)不互质时,斜率a/b与a/gcd(a,b)和b/gcd(a,b)斜率相等,那么一定会被(a/gcd(a,b),b/gcd(a,b))挡住

那就是求\(\sum_{i=1}^{n}\sum_{j=1}^{n} gcd(i,j)=1\)

求个欧拉就好了QAQ

线性求欧拉\(O(n)\)

#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
int n;
const int maxn =400004;
int phi[maxn];
void get_phi() {
    phi[1]=1;
    for(int i=2; i<=n; i++) {
        if(!phi[i])
            for(int j=i; j<=n; j+=i) {
                if(!phi[j])phi[j]=j;
                phi[j]=phi[j]/i*(i-1);
            }
    }
}
int main() {
    scanf("%d",&n);
    get_phi();
    int ans=0;
    for(int i=1; i<=n-1; i++)ans+=phi[i];
    printf("%d",2*ans+1);
    return 0;
}

单个求欧拉

#include<cstdio>
using namespace std;
const int maxn = 1110101;
int oula[maxn];
int prime[maxn];
bool a[maxn];
int n;
int phi(int x) {
    int ret=1;
    for(int i=2;i*i<=x;i++) {
        if(x%i==0) {
            ret*=i-1,x/=i;
            while(x%i==0) {
                ret*=i;x/=i;
            }
        }
    }
    if(x>1)ret*=x-1;
    return ret;
}

int main () { 
    scanf("%d",&n);
    int ans=0;
    for(int i=1;i<n;i++) {
        ans+=phi(i);
    }
    ans=ans*2,ans+=1;
    printf("%d\n",ans);
    return 0;
}

bzoj 2190: [SDOI2008]仪仗队

标签:std   max   return   class   ref   技术分享   分享图片   stream   src   

原文地址:https://www.cnblogs.com/sssy/p/8407197.html

(0)
(0)
   
举报
评论 一句话评论(0
登录后才能评论!
© 2014 mamicode.com 版权所有  联系我们:gaon5@hotmail.com
迷上了代码!