[Tyvj1655] 游乐园 二分查找

Problem

题意:有n(<=1e10)个人,每个人会坐当前空闲的,编号最小的飞机(<=1000),对于第i个飞机,任意人的乘坐时间为si。

Analisis

n的数量很惊人,不能模拟,所以第一次我考虑从m下手,又怎么做呢?
Dp ? 贪心 ? 似乎无从下手。
正解: 可以发现坐飞机的时间是有规律的,那么这就意味着如果确定了时间,可以在O(m)的时间内求出有多少人坐了飞机。那么就二分找到最后一个人上飞机的时刻,模拟一下即可。
Ps:代码中的 (Time - 1) % s[i] == 0 就代表了在这个时刻可以上飞机,很重要

/*I am firing!*/
#include
#include
#include
#include
using namespace std;
typedef int _int;
#define int long long
int n , m , s[1005];
int Calc(int Time)
{
    int sum = 0;
    for(int i=1;i<=m && sum1+s[i]) / s[i];
    return sum;
}
int Getnum(int Time)
{
    int tot = n - Calc(Time-1);
    Time--;
    /*这里是为了模拟,因为在Time时刻人坐上飞机了
    计算的却是Time时刻之前的数量*/
    for(int i=1;i<=m;i++)
        if(!(Time % s[i]))
            if(!(--tot))
                return i;
}

_int main()
{
    cin>>n>>m;
    for(int i=1;i<=m;i++) cin>>s[i];
    int L = 0 , R = 1e15;
    while(L <= R)
    {
        int mid = (L + R) >> 1;
        if(Calc(mid) < n) L = mid + 1;
            else R = mid - 1;
    }
    cout<return 0;
}

你可能感兴趣的:(二分,脑洞题)