"Euler's Theorem" [SDOI2008] Guard of honor

[SDOI2008] Guard of Honor

https://ac.nowcoder.com/acm/problem/20313

topic description

As a sports committee member, Mr. C is responsible for the training of the guard of honor for this sports meeting.

The guard of honor is an N*N phalanx composed of students. In order to ensure that the team is uniform during the march, Mr. C will follow the left rear of the guard of honor and judge whether the team is neat according to the number of students in his sight (as shown in the picture below).

1644234514514

Now, Mr. C wants you to tell him the number of students he can see when the team is in order.

enter description

A total of one number N.

output description

A total of one number, that is, the number of students Mr. C should see.

sample

#1

4
9

hint

  • For 100% of the data, 1 ≤ N ≤ 40000 1 \le N \le 400001N40000

analyze

1644237028500

AC Code

public class Main {
    
    
    static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
    static StreamTokenizer st = new StreamTokenizer(br);
    static PrintWriter out = new PrintWriter(new BufferedOutputStream(System.out));
    
    static final int MAX = 40005;
    static int[] prime = new int[MAX];
    static int[] euler = new int[MAX];
    static boolean[] vis = new boolean[MAX];
    static int cnt;
    
    public static void main(String[] args) throws Exception {
    
    
        int n = nextInt();
        eulers(n);
        int ans = 0;
        for(int i = 1; i <= n - 1; i++) {
    
    
            ans += euler[i];
        }
        ans = ans * 2 + 1;
        System.out.println(ans);
    }
    
    public static void eulers(int n) {
    
    
        euler[1] = 1;
        for(int i = 2; i <= n; i++) {
    
    
            if(!vis[i]) {
    
     // 判断是不是素数
                prime[++cnt] = i;
                euler[i] = i - 1;
            }
            for(int j = 1; j <= cnt && i * prime[j] <= n; j++) {
    
    
                vis[prime[j] * i] = true; // 将 prime[j] * i 标识为不是素数
                if(i % prime[j] == 0) {
    
     // 判断 prime[j] 是否为 i 的约数
                    euler[prime[j] * i] = euler[i] * prime[j];
                    break;
                } else {
    
    
                    // prime[j] - 1 就是 euler[prime[j]],利用了欧拉函数的积极性
                    euler[prime[j] * i] = euler[i] * (prime[j] - 1);
                }
            }
        }
    }
    
    public static int nextInt() throws Exception {
    
    
        st.nextToken();
        return (int) st.nval;
    }
    
    public static String nextStr() throws Exception {
    
    
        st.nextToken();
        return st.sval;
    }
}

ring nextStr() throws Exception {
st.nextToken();
return st.sval;
}
}


Guess you like

Origin blog.csdn.net/qq_43098197/article/details/130437918