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個(gè)人,每個(gè)人都有一個(gè)編號(hào),編號(hào)都是1-n的數(shù),且每個(gè)人的編號(hào)都不相同
你每次可以申請(qǐng)一個(gè)表去詢問(wèn)最多m個(gè)不同的人,他們的編號(hào)是哪些,但是你不知道編號(hào)和這m個(gè)人的對(duì)應(yīng)關(guān)系
然后問(wèn)你最少申請(qǐng)多少次,可以清楚知道這n個(gè)人的具體編號(hào)
題解:
每周一題 題解
div2 智商杯考試
首先這道題正面想比較麻煩。
現(xiàn)在我們假設(shè)你知道了MaxN(m,k),即表示每次最多提及m個(gè)問(wèn)題,我詢問(wèn)k次,最多知道多少個(gè)答案和題目對(duì)應(yīng)的這個(gè)函數(shù)。
那么我直接二分答案就好了
只要解決了MaxN(m,k),那么原題就解決了。
然后怎么去處理這個(gè)呢?
我們這樣想,我們一開(kāi)始有n個(gè)k位二進(jìn)制數(shù),如果在第i輪回答中提及到了第j個(gè)問(wèn)題的話,那么就令第j個(gè)二進(jìn)制數(shù)的第i位為1。
分析一下樣例一,n = 4,k = 2,m = 2的情況:
1 0 1 0
1 1 0 0
可以看到第一個(gè)問(wèn)題的序列是11,第二個(gè)問(wèn)題的序列是01,第三個(gè)是10,第四個(gè)是00
由于這些二進(jìn)制數(shù)都不一樣,因此你能分辨出來(lái)。
只要我們最后的n個(gè)k位二進(jìn)制數(shù)全部不一樣,你就能分辨。
這個(gè)證明也很簡(jiǎn)單,如果有兩個(gè)二進(jìn)制數(shù)相同的話,那么肯定就可以交換著兩個(gè)的問(wèn)題的對(duì)應(yīng)關(guān)系了。
那么我們?cè)趺慈ピ儐?wèn),才能使得1的個(gè)數(shù)盡量少,且問(wèn)的問(wèn)題多呢?
貪心。
C(k,0)個(gè)問(wèn)題,我不提及;C(k,1)個(gè)問(wèn)題,我就只提及一次;C(k,2)個(gè)問(wèn)題,我提及兩次........C(k,r)個(gè)問(wèn)題,我提及r次。
這樣,最后的矩陣構(gòu)造是這樣的:
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一下整個(gè)矩陣的1的個(gè)數(shù)是否超過(guò)k*m,。
于是,這道題就解決了!
有人問(wèn),為什么我們只用check總共1的個(gè)數(shù)是否超過(guò)k*m,而不去check每一行的1的個(gè)數(shù)是否超過(guò)m。
其實(shí)你去check兩個(gè)也是可以的,這個(gè)復(fù)雜度在本題也是可以接受的。
但是為什么呢?
證明如下:
假設(shè)我們滿足總共1的個(gè)數(shù)不超過(guò)k*m,但是存在某一些位的1的個(gè)數(shù)超過(guò)了m。
那么必然存在一些位的1的個(gè)數(shù)少于m。
我們選擇其中一個(gè)超過(guò)m的位X,選擇其中一個(gè)少于m的位Y。
然后我們?cè)購(gòu)膎個(gè)串中找到x個(gè)在X位為1,Y位為0的串,找到y(tǒng)個(gè)在X位中為0,Y位中為1的串。
也是顯然知道x>y。
對(duì)于x個(gè)串,我們都將第X位置成0,Y位置成1,顯然這x個(gè)串仍然都是各不相同的,且最多在y串中找到一個(gè)和他相同的。
因?yàn)閤>y,所以肯定能夠找到一個(gè)串是在y串沒(méi)有與之對(duì)應(yīng)的,那么我們只要變這個(gè)串就好了。
這樣我們就得到了,X位置的1的總數(shù)-1,Y位置的1的總數(shù)+1了。
所以只要滿足總共1的個(gè)數(shù)不要超過(guò)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());} }轉(zhuǎn)載于:https://www.cnblogs.com/qscqesze/p/5196982.html
總結(jié)
以上是生活随笔為你收集整理的Codeforces Round #127 (Div. 1) E. Thoroughly Bureaucratic Organization 二分 数学的全部?jī)?nèi)容,希望文章能夠幫你解決所遇到的問(wèn)題。
- 上一篇: lunix 安装python3
- 下一篇: C#调用WebService实例和开发(