題目描述
從前有乙個奇怪的商店,一共售賣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...