hihocoder 1298 : 數論五·歐拉函數

hihocoder 1298

描述

小Hi和小Ho有時候會用密碼寫信來互相聯繫,他們用了一個很大的數當做密鑰。小Hi和小Ho約定了一個區間[L,R],每次小Hi和小Ho會選擇其中的一個數作爲密鑰。

小Hi:小Ho,這次我們選[L,R]中的一個數K。

小Ho:恩,小Hi,這個K是多少啊?

小Hi:這個K嘛,不如這一次小Ho你自己想辦法算一算怎麼樣?我這次選擇的K滿足這樣一個條件:

假設φ(n)表示1..n-1中與n互質的數的個數。對於[L,R]中的任意一個除K以外的整數y,滿足φ(K)≤φ(y)且φ(K)=φ(y)時,K<y。

也即是K是[L,R]中φ(n)最小並且值也最小的數。

小Ho:噫,要我自己算麼?

小Hi:沒錯!

小Ho:好吧,讓我想一想啊。

<幾分鐘之後...>

小Ho:啊,不行了。。感覺好難算啊。

小Hi:沒有那麼難吧,小Ho你是怎麼算的?

小Ho:我從枚舉每一個L,R的數i,然後利用輾轉相除法去計算[1,i]中和i互質的數的個數。但每計算一個數都要花好長的時間。

小Hi:你這樣做的話,時間複雜度就很高了。不妨告訴你一個巧妙的算法吧:

提示:歐拉函數

輸入

第1行:2個正整數, L,R,2≤L≤R≤5,000,000。

輸出

第1行:1個整數,表示滿足要求的數字K


樣例輸入

4 6

樣例輸出

4

Solution

歐拉函數的板子題

Code

#include <iostream>
#include <cstdio>
#include <cstdlib>
#include <cstring>
#include <algorithm>
#include <cmath>
#include <stack>
#include <map>
#include <vector>
#include <queue>
#define LL long long
#define L 5000010
using namespace std;

int l, r, phi[L], minx = L, ans;

int main() {
  scanf("%d %d", &l, &r);
  phi[1] = 1;
  for (int i = 2; i <= r; ++i)
    if (!phi[i])
      for (int j = i; j <= r; j += i) {
	if (!phi[j]) phi[j] = j;
	phi[j] = phi[j] / i * (i - 1);
      }
  for (int i = l; i <= r; ++i)
    if (phi[i] && phi[i] < minx) minx = phi[i], ans = i;
  printf("%d\n", ans);
  return 0;
}

Summary

注意找最小phi值的時候minx要賦初值

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章