Codeforces Round #127 (Div. 1) E. Thoroughly Bureaucratic Organization 二分 数学
題目連接:
http://www.codeforces.com/contest/201/problem/E
Description
Once n people simultaneously signed in to the reception at the recently opened, but already thoroughly bureaucratic organization (abbreviated TBO). As the organization is thoroughly bureaucratic, it can accept and cater for exactly one person per day. As a consequence, each of n people made an appointment on one of the next n days, and no two persons have an appointment on the same day.
However, the organization workers are very irresponsible about their job, so none of the signed in people was told the exact date of the appointment. The only way to know when people should come is to write some requests to TBO.
The request form consists of m empty lines. Into each of these lines the name of a signed in person can be written (it can be left blank as well). Writing a person's name in the same form twice is forbidden, such requests are ignored. TBO responds very quickly to written requests, but the reply format is of very poor quality — that is, the response contains the correct appointment dates for all people from the request form, but the dates are in completely random order. Responds to all requests arrive simultaneously at the end of the day (each response specifies the request that it answers).
Fortunately, you aren't among these n lucky guys. As an observer, you have the following task — given n and m, determine the minimum number of requests to submit to TBO to clearly determine the appointment date for each person.
Input
The first line contains a single integer t (1?≤?t?≤?1000) — the number of test cases. Each of the following t lines contains two integers n and m (1?≤?n,?m?≤?109) — the number of people who have got an appointment at TBO and the number of empty lines in the request form, correspondingly.
Output
Print t lines, each containing an answer for the corresponding test case (in the order they are given in the input) — the minimum number of requests to submit to TBO.
Sample Input
5
4 1
4 2
7 3
1 1
42 7
Sample Output
3
2
3
0
11
Hint
題意
有n個人,每個人都有一個編號,編號都是1-n的數,且每個人的編號都不相同
你每次可以申請一個表去詢問最多m個不同的人,他們的編號是哪些,但是你不知道編號和這m個人的對應關系
然后問你最少申請多少次,可以清楚知道這n個人的具體編號
題解:
每周一題 題解
div2 智商杯考試
首先這道題正面想比較麻煩。
現在我們假設你知道了MaxN(m,k),即表示每次最多提及m個問題,我詢問k次,最多知道多少個答案和題目對應的這個函數。
那么我直接二分答案就好了
只要解決了MaxN(m,k),那么原題就解決了。
然后怎么去處理這個呢?
我們這樣想,我們一開始有n個k位二進制數,如果在第i輪回答中提及到了第j個問題的話,那么就令第j個二進制數的第i位為1。
分析一下樣例一,n = 4,k = 2,m = 2的情況:
1 0 1 0
1 1 0 0
可以看到第一個問題的序列是11,第二個問題的序列是01,第三個是10,第四個是00
由于這些二進制數都不一樣,因此你能分辨出來。
只要我們最后的n個k位二進制數全部不一樣,你就能分辨。
這個證明也很簡單,如果有兩個二進制數相同的話,那么肯定就可以交換著兩個的問題的對應關系了。
那么我們怎么去詢問,才能使得1的個數盡量少,且問的問題多呢?
貪心。
C(k,0)個問題,我不提及;C(k,1)個問題,我就只提及一次;C(k,2)個問題,我提及兩次........C(k,r)個問題,我提及r次。
這樣,最后的矩陣構造是這樣的:
0 1 0 0 1 1 ... 1
0 0 1 0 1 0 ... 1
0 0 0 1 0 1 ... 1
. . . . . . ... 1
. . . . . . ... 1
0 0 0 0 0 0 ... 1
然后最后再Check一下整個矩陣的1的個數是否超過k*m,。
于是,這道題就解決了!
有人問,為什么我們只用check總共1的個數是否超過k*m,而不去check每一行的1的個數是否超過m。
其實你去check兩個也是可以的,這個復雜度在本題也是可以接受的。
但是為什么呢?
證明如下:
假設我們滿足總共1的個數不超過k*m,但是存在某一些位的1的個數超過了m。
那么必然存在一些位的1的個數少于m。
我們選擇其中一個超過m的位X,選擇其中一個少于m的位Y。
然后我們再從n個串中找到x個在X位為1,Y位為0的串,找到y個在X位中為0,Y位中為1的串。
也是顯然知道x>y。
對于x個串,我們都將第X位置成0,Y位置成1,顯然這x個串仍然都是各不相同的,且最多在y串中找到一個和他相同的。
因為x>y,所以肯定能夠找到一個串是在y串沒有與之對應的,那么我們只要變這個串就好了。
這樣我們就得到了,X位置的1的總數-1,Y位置的1的總數+1了。
所以只要滿足總共1的個數不要超過k*m就好了。
代碼
#include <cstdio>#define LL long longusing namespace std;int T, n, m;inline bool ok(LL k){LL t = k * m, cnt = 1, tmp = 1;for (LL i = 1; i <= k; i++){tmp = tmp * (k - i + 1) / i;if (i <= t / tmp) t -= i * tmp, cnt += tmp;else{cnt += t / i; break;}}return cnt >= n; }inline LL calc(){LL l = 0, r = n;while (l < r){LL mid = (l + r) >> 1;if (ok(mid)) r = mid; else l = mid + 1;}return r; }int main(){for (scanf("%d", &T); T--;){scanf("%d%d", &n, &m);if (m + m > n) m = n / 2;printf("%I64d\n", calc());} }轉載于:https://www.cnblogs.com/qscqesze/p/5196982.html
總結
以上是生活随笔為你收集整理的Codeforces Round #127 (Div. 1) E. Thoroughly Bureaucratic Organization 二分 数学的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: lunix 安装python3
- 下一篇: Gina DLL