• 仪仗队(容斥,欧拉,打表)


    Description

      作为体育委员,C君负责这次运动会仪仗队的训练。仪仗队是由学生组成的N * N的方阵,为了保证队伍在行进中整齐划一,C君会跟在仪仗队的左后方,根据其视线所及的学生人数来判断队伍是否整齐(如下图)。       现在,C君希望你告诉他队伍整齐时能看到的学生人数。

    Input

      共一个数N。

    Output

      共一个数,即C君应看到的学生人数。

    Sample Input

      4

    Sample Output

      9

    Hint

    【数据规模和约定】   对于 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("
    ");
    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
    ",getn(i,N));
    48         }
    49         printf("%lld
    ",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
    ",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
    ",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
    ",2*dp[N-1]+1);
        }
        return 0;
    }
     
  • 相关阅读:
    最大子段和问题
    moore voting algorithm for majority element in vector
    linux命令 wget
    一道简单的局部链表反转的问题,具体解决时的麻烦的分类
    20145215《网络对抗》Exp2 后门原理与实践
    20145215《网络对抗》shellcode注入&Return-to-libc攻击深入
    20145215卢肖明《网络对抗》逆向及Bof基础
    20145215《信息安全系统设计基础》课程总结
    20145215&20145307《信息安全系统设计基础》实验五 网络通信
    20145215《信息安全系统设计基础》第十四周学习总结
  • 原文地址:https://www.cnblogs.com/handsomecui/p/5282734.html
Copyright © 2020-2023  润新知