商店 分塊 二分

2021-10-05 14:30:53 字數 1786 閱讀 4229

題目描述

從前有乙個奇怪的商店,一共售賣k種物品,第i種物品的初始**為i。

但是這商店有個很奇怪的規矩,就是你每次購買一樣物品之後,這種物品的**都會在當前基礎上翻一倍。

現在我們想要用最少的錢從裡面買n樣物品,不限購買的物品種數和每種物品購買的次數,請求出若這樣做,所買到的最貴的物品的**,由於這個數字可能過大,你只需要輸出其模1000000007=10^9+7的結果即可。

輸入每個測試點第一行乙個整數t,表示資料組數。

接下來t行,每行兩個正整數n,k。

輸出t行,第i行表示第i組資料的答案。

樣例輸入 copy

5

3 13 2

5 31000000000 1

987654321 876543210

樣例輸出 copy

424

570312504

493827168

提示

對於100%的資料,1≤t≤2000,1≤n,k≤10^9。

分兩種情況;

1.答案小於等於k

2.答案大於k

對於第一種情況,直接二分答案,對於每乙個二分的答案x,計算

對於第二種情況,首先算出**為k時所能買到的物品數量為mx,那麼剩餘需要買的數量為num1=n-mx,因為1~n這些數*2的比n大的數在[n+1,2*n]這個範圍裡直接對應,並且這個[n+1,2*n]出現的數為n個數,對於[2*n+1,4*n]這個範圍也是如此,並且每乙個數之間的大小關係不發生變化,所以,我們只要求出有num1/n個這樣的完整區間,然後剩下的num1%n在[n/2+1,n]區間中找即可。

複雜度為(t*sqrt(k)*log(k))

update:至於為啥在[n/2+1,n]這個區間找是因為如果在[1,n/2]這個區間,裡面任何數的2倍還是在[1,n]之間

/**/

#pragma gcc optimize(3,"ofast","inline")

#include #include #include #include #include #include #include #include #include #include #include #include typedef long long ll;

using namespace std;

const long long mod = 1e9 + 7;

int t, n, k;

ll mx;

int check(int x)

mx = max(mx, ans);

return ans >= k;

}int get(int x)

return ans;

}int check1(int x, int num)

return ans >= num;}

ll poww(ll x, ll num)

return res;}

int main()

printf("%lld\n", (ans << 1) * poww(2, num2) % mod);

continue;

}int l = 0, r = n, ans = n;

while(l <= r)

printf("%d\n", ans);

}return 0;}/*

63 1

3 25 3

1000000000 1

987654321 876543210

6 3*/

商店繁榮度(二分查詢)

題目描述 在一條繁華的街道上有n個商店,每個商店都有乙個繁華度a i。lzy現在想知道,每個商店的右邊有沒有其它商店繁華度比當前商店低的。對於每個商店,找到它右邊最遠位置pos,滿足a pos a i,輸出 pos i 1,若右邊沒有比當前商店繁華度低的,則輸出 1 輸入 測試樣例由多組測試資料組成...

分塊 二分 BZOJ 3343

time limit 10 sec memory limit 256 mb submit 1312 solved 585 submit status discuss 教主最近學會了一種神奇的魔法,能夠使人長高。於是他準備演示給xmyz資訊組每個英雄看。於是n個英雄們又一次聚集在了一起,這次他們排成了...

nefu 復讀機 分塊加二分

有兩個操作,1操作,對於x,y區間內的值全部加1。2操作,求出第一次復讀y次跟最後乙個復讀y次的復讀機次數。a存復讀機原陣列,b存分塊陣列,對於分塊陣列每個進行排序操作,使區間有序,每次查詢對於第乙個區間查詢到最後乙個區間,進行二分查詢。更新時則對兩個區間都進行更新。也可對a更新後再對b賦值。inc...