數論 又是畢業季I 又是畢業季II

2021-10-06 00:26:00 字數 2031 閱讀 7949

題目簡化

為了把畢業晚會辦得更好,老師想要挑出默契程度最大的 k 個人參與畢業晚會彩排。可是如何挑呢?老師列出全班同學的號數 1,2,…,n 並且相信 k 個人的默契程度便是他們的最大公約數(這不是迷信哦~)。這可難為了他,請你幫幫忙吧!

輸入格式:

兩個空格分開的正整數n和k。(n>=k>=1)k<=1e9,n<=1e9

輸出格式:

乙個整數,為最大的默契值。

input

4 2output

2

思路

一開始很容易想到列舉n個數取k個的所有組合,然後分別用輾轉相除法求最大公約數,但是複雜度明顯不符合要求,於是必須換一種思路。

先設最大公約數為x,x*1 ,x*2 ...... x*k,即x的1~k倍,但必須保證x*k<=n,所以x<=n/k,又因為x為整數,所以x<=[n/k](取整)

參考題解

首先,若可能的最大公約數為a,取出的k個數為x1,x2,……,xk且滿足x1=a,x2>=2a,……,xk>=ka。又∵xk<=n,∴n>=ka,∴a<=n/k,又∵a為整數,∴a<=[n/k](為取整符號)。

另一方面,我們取[n/k],2*[n/k],……,k*[n/k],它們的最大公約數a=[n/k],且它們都小於等於n大於等於1,且互不相等,滿足條件。

∴答案即為[n/k]。

#include

#include

using

namespace std;

long

long n,k;

intmain()

題目描述

彩排了一次,老師不太滿意。當然啦,取每位同學的號數來找最大公約數顯然不太合理。於是老師給每位同學評了乙個能力值。於是現在問題變為,從n個學生中挑出k個人使得他們的默契程度(即能力值的最大公約數)最大。但因為節目太多了,而且每個節目需要的人數又不知道。老師想要知道所有情況下能達到的最大默契程度是多少。這下子更麻煩了,還是交給你吧~

ps:乙個數的最大公約數即本身。

輸入格式

第一行乙個正整數n。n<=10000,inf<=1e6

第二行為n個空格隔開的正整數,表示每個學生的能力值。

輸出格式

總共n行,第i行為k=i情況下的最大默契程度。

input

41 2 3 4

output42

11

題解

題解鏈結

我們想到k個數的公約數含義就是這k個數均含有某個因數,如果我們把所有數的因數全部求出來,發現有k個數均含有某個因數,那麼這個數必然是這k個數的公約數

其中找出最大的就是它們的最大公約數。但是要如何高效的做到這點呢?

考慮到對於k=1,2……,n都要求出,我們可以這麼做:

求出每個因數出現的次數

對於每個次數記錄最大的因數

記錄能力最大值之後用while語句將其不斷減小(因為k=1時顯然最大公約數為最大能力值,之後的公約數顯然小於等於前乙個數)

// 空間複雜度o(n*sqrt(maxn))

#include

using

namespace std;

int n,maxn,x,cnt[

1000010];

intmain()

}for

(int i=

1;i<=n;

++i)

}

**思路,編輯格式不易,大家覺得還可以可以點讚、收藏、關注一下吧!

也可以到我的個人部落格參觀一下,

又是畢業季I

對於答案a,k a是最接近 n的,即 a n k 下取整 所以直接輸 n k即可。我的方法是 二分查詢 n k真的沒有想到唉。我找的最大公約數,如果當前的mid對應的個數比k大,就往大了找,否則往小裡找,對於邊界問題,要加一些特判。includeusing namespace std intn,k ...

又是畢業季1 又是畢業季2

又是畢業季2 n k 又是畢業季2 一開始很容易想到列舉n個數取k個的所有組合,然後分別用輾轉相除法求最大公約數,但是複雜度明顯不符合要求,於是必須換一種思路。我們想到,k個數的公約數含義就是這k個數均含有某個因數,如果我們把所有數的因數全部求出來,發現有k個數均含有某個因數,那麼這個數必然是這k個...

luogu P1414 又是畢業季II

題目傳送門 題意 有n個數,求每k k從1列舉至n 個數的最大公約數。思路 我們可以知道,每乙個數可以進行分解,統計每乙個數做因子時所出現個個數total。語文不好,舉個例子吧。因子 數12 34total11 1114 2010 1230 0101 4000 11我們可以發現,total為結果。證...