CodeForces 830C 奇怪的降複雜度

2021-08-07 10:48:05 字數 1671 閱讀 5381

description有n棵竹子,初始時每棵竹子高度都是0,每棵竹子每天長高1m

對於每棵竹子,我們不希望其高度超過a[i],如果超過了,我們就會把超過的部分減去

奇怪的是減去之後竹子就不會再長了

我們不希望每天去看一下竹子的情況,希望每隔d天去看一下竹子的情況

本著愛護環境的原則,我們不希望減去的竹子長度之和大於k

我們最多可以隔多少天去看一次竹子?

input

第一行兩個整數n,k

第二行n隔整數表示a[i]

output

乙個整數表示答案,即最大的d值

hint

20%:ai<=5*10^5

另有20%:k<=1

100%:1<=n<=100,0<=k<=10^11,1<=ai<=10^9

這道題我還愣是問大佬問了好久才搞懂。

第一眼:而不是二分嘛,水!結果考試快結束是才反應過來這答案並不滿足二分的性質。如:4 4 4,d選4比選3優。

那麼怎麼辦呢?

首先可以明確,d一定小於a[i]的最大值。那麼這個d就太多了啊。如果直接暴力去for d,肯定是不行的,只能得20分。我們希望可以減少一些無用的d的列舉。

先可以得到公式:

轉化一下:

我們可以發現,對於[ai/d]向上取整,有多個d對應相同的值。如:10/d,d=5,6,7,8,9都對應乙個值2,可以證明d的數量是o(√n)

我們記錄每乙個ai對應的d,其中d可以代表一系列d。在算出了sigma([ai/d])後,可以根據上面的公式求出最大的d

暴力列舉得出的d,複雜度o(n*ai^0.5)

詳情看**吧。。。解釋起來好麻煩。。

#include

#include

#include

#define ll long long

using namespace std;

const int n=105;

const int m=100000+5;

ll a[n],n,k,c=0;

ll ans=0,tot=0,vec[n*m],cnt=0;

int main()

c+=k;

sort(vec+1,vec+cnt+1);

cnt=unique(vec+1,vec+cnt+1)-(vec+1);

for(int i=1;i<=cnt;i++)

printf("%lld",ans);

return

0;}

總結:

1、在想二分時可以舉例子來驗證答案的單調性

2、把公式寫出來時,可以結合一些數論的知識,看看能不能化簡

CodeForces 830C 奇怪的降複雜度

description有n棵竹子,初始時每棵竹子高度都是0,每棵竹子每天長高1m 對於每棵竹子,我們不希望其高度超過a i 如果超過了,我們就會把超過的部分減去 奇怪的是減去之後竹子就不會再長了 我們不希望每天去看一下竹子的情況,希望每隔d天去看一下竹子的情況 本著愛護環境的原則,我們不希望減去的竹...

Codeforces830A 二分 貪心

二分其實很好考慮對吧,時間越多,滿足的越多,如何judge呢,這個仔細想想還是挺有意思的.1.左邊的人拿左邊的鑰匙能在這個時間段滿足,那就滿足,對於整體方案來說是最優的 2.如果左邊的對於某把鑰匙不滿足,之後出現了某個位置鑰匙滿足,那麼之前那把鑰匙一定是在這個人的左邊,那麼進而證明右邊的人也一定不會...

c 奇階幻方

奇階幻方的產生規則 將1放在第一行中間一列 從2開始直到n n止各數依次按下列規則存放 按 45 方向行走,如向右上 每乙個數存放的行比前乙個數的行數減1,列數加1 如果行列範圍超出矩陣範圍,則迴繞。如果按上面規則確定的位置上已有數,或上乙個數是第1行第n列時,include include usi...