Easy Scheduling

Easy Scheduling

Eonathan Eostar decided to learn the magic of multiprocessor systems. He has a full binary tree of tasks with height h. In the beginning, there is only one ready task in the tree — the task in the root. At each moment of time, p processes choose at most p ready tasks and perform them. After that, tasks whose parents were performed become ready for the next moment of time. Once the task becomes ready, it stays ready until it is performed.

You shall calculate the smallest number of time moments the system needs to perform all the tasks.

Input
The first line of the input contains the number of tests t (1≤t≤5⋅105). Each of the next t lines contains the description of a test. A test is described by two integers h (1≤h≤50) and p (1≤p≤104) — the height of the full binary tree and the number of processes. It is guaranteed that all the tests are different.

Output
For each test output one integer on a separate line — the smallest number of time moments the system needs to perform all the tasks.

Example
Input

3
3 1
3 2
10 6

Output
7
4
173

Note
Let us consider the second test from the sample input. There is a full binary tree of height 3 and there are two processes. At the first moment of time, there is only one ready task, 1, and p1 performs it. At the second moment of time, there are two ready tasks, 2 and 3, and the processes perform them. At the third moment of time, there are four ready tasks, 4, 5, 6, and 7, and p1 performs 6 and p2 performs 5. At the fourth moment of time, there are two ready tasks, 4 and 7, and the processes perform them. Thus, the system spends 4 moments of time to perform all the tasks.

题意: 给个高度为h的二叉树,一次最多执行p个任务,当根节点执行完后,其子节点准备就绪,才能被执行

AC代码:

#include<stdio.h>
#include<string.h>
#include<cmath>
#define ll long long//int最大到2^31-1,题中h<=50,故用long long
#include<algorithm>
using namespace std;
int main()
{
	ll t,h,p;
	scanf("%lld",&t);
	while(t--)
	{
		ll sum=1,a=0;//初始执行根节点1花费1分钟
		scanf("%lld%lld",&h,&p);
		for(ll i=1;i<h;i++)
		{
			ll k=pow(2,i)-a;//a为这一层已经执行过的节点数
			a=0;
			if(k<=p)//当前这一层节点数<=最大执行数,一次执行完毕
			sum++;//花费一分钟
			else//一次执行不完
			{
				if(k%p!=0)//执行最大次数后剩余的有节点数
				{
					sum++;//再执行一次
					a=p-(k%p);//k%p为当前层剩余的节点数,p-(k%p)表示上述再执行一次后,下一层执行了几个节点,下次运算减掉这几个执行过的
				}
				sum+=k/p;//加上执行的最大次数
			}
		}
		printf("%lld\n",sum);
	}
	return 0;
}
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值