【NOIP Round #6】重生题解

猫有九条命,但你有 114514 条命。

题目描述

你有 n 个任务需要完成,第 i 个任务需要 ti 天。但人的寿命有限,你只剩下 c 天了。

磨刀不误砍柴工,你可以花 1 天时间对第 i 个任务进行深入思考,那么它所需的时间会减少 di 天。特别的,如果时间被减为零或负数,这个任务就能被瞬间完成。但人的灵感有限,在一次生命里每个任务只能被深入思考一次。

你可以复活,每次复活会再给你带来 c 天。之前的深入思考的结果会一直保留,不会因复活而消失。

求出你最少需要复活多少次,才能在最后一条命把所有任务都完成。你可以认为在最后一条命之前你并不能做任务,只能对任务进行思考,而在最后一条命既可以思考也可以做任务。

输入格式

第一行一个正整数 T ,表示数据组数。每组数据的格式如下:

  • 第一行两个正整数 n,c ,表示任务的个数,以及一条命的长度。
  • 接下来 n 行,每行两个正整数 ti,di ,描述一个任务。

输出格式

对每组数据,输出一行一个非负整数,表示最少需要复活多少次。

样例 1

input
2
3 5
17 5
5 2
15 4
2 1345
1344 1
10 10
output
3
0
explanation

对于第一组数据:

在前三条命,分别把每个任务都深入思考一次,那么任务所需的时间就分别降为 2,0,3 。

在最后一条命,对任务 1 和任务 3 进行深入思考,然后瞬间完成所有任务。

共用四条命,复活三次。可以证明不存在复活次数小于 3 的方案。

对于第二组数据:

先对第二个任务深入思考,然后瞬间完成第二个任务,然后在接下来的 1344 天里完成第一个任务。

样例 2

input
1
3 1
1000000000 1
1000000000 1
1000000000 1
output
2999999999

样例 3∼6

见下发文件中的 ex_rebirth*.in/ex_rebirth*.ans ,它们分别对应第 2∼5 个子任务。

数据范围

本题采用捆绑测试,你需要通过一个子任务的所有测试点才能得到子任务的分数。

对于所有数据,1≤T≤1000,1≤∑n≤2×105,1≤c≤109,1≤di≤ti≤109 。

子任务编号特殊性质分值
1∑n,∑ti≤710
2n,ti≤30,T≤10020
3∑n≤300020
4c≥n20
530

思路

二分即可。

代码见下

#include<bits/stdc++.h> 
using namespace std;
long long tt,n,c,sd=0;
struct one{
	long long t,d,a;
}a[200005];
bool cmp(one a1,one b1){
	if(a1.d!=b1.d){
		return a1.d>b1.d;
	}
	else{
		return a1.t>b1.t;
	}
}
inline long long read(){
	long long x=0;
	char s=getchar();
	while(s<'0'||s>'9'){
		s=getchar();
	}
	while(s>='0'&&s<='9'){
		x=(x<<3)+(x<<1)+(s^48);
		s=getchar();
	}
	return x;
}
inline bool abc(long long a1){
	long long jk=c*a1,fs=0;
	for(int i=1;i<=n;i++){
		if(a[i].a<=a1-1){
			jk-=a[i].a;
		}
		else if(a[i].a==a1){
			jk-=a1;
			fs++;
		}
		else{
			jk-=a1;
			jk-=(a[i].t-a[i].d*a1);
			fs+=(a[i].t-a[i].d*a1);
			fs++;
		}
		//cout<<a1<<" "<<jk<<" "<<fs<<endl;
		if(jk<=-1||fs>=c+1){
			return 0;
		}
	}
	return 1;
}
int main(){
	freopen("rebirth.in","r",stdin);
	freopen("rebirth.out","w",stdout);
	cin>>tt;
	while(tt--){
		cin>>n>>c;
		sd=0;
		for(int i=1;i<=n;i++){
			a[i].t=read();
			a[i].d=read();
			if(a[i].t%a[i].d==0){
				a[i].a=a[i].t/a[i].d;
			}
			else{
				a[i].a=a[i].t/a[i].d+1;
			}
			sd+=a[i].t; 
		}
		sort(a+1,a+n+1,cmp);
		long long l=1,r=(9e18)/c,md=1e18+7;
		while(l<=r){
			long long mid=(l+r)/2;
			if(abc(mid)==1){
				md=min(md,mid);
				r=mid-1;
			}
			else{
				l=mid+1;
			}
		}
		cout<<md-1<<endl;
	}
	return 0;
}

#include<bits/stdc++.h> 
using namespace std;
long long tt,n,c,sd=0;
struct one{
    long long t,d,a;
}a[200005];
bool cmp(one a1,one b1){
    if(a1.d!=b1.d){
        return a1.d>b1.d;
    }
    else{
        return a1.t>b1.t;
    }
}
inline long long read(){
    long long x=0;
    char s=getchar();
    while(s<'0'||s>'9'){
        s=getchar();
    }
    while(s>='0'&&s<='9'){
        x=(x<<3)+(x<<1)+(s^48);
        s=getchar();
    }
    return x;
}
inline bool abc(long long a1){
    long long jk=c*a1,fs=0;
    for(int i=1;i<=n;i++){
        if(a[i].a<=a1-1){
            jk-=a[i].a;
        }
        else if(a[i].a==a1){
            jk-=a1;
            fs++;
        }
        else{
            jk-=a1;
            jk-=(a[i].t-a[i].d*a1);
            fs+=(a[i].t-a[i].d*a1);
            fs++;
        }
        //cout<<a1<<" "<<jk<<" "<<fs<<endl;
        if(jk<=-1||fs>=c+1){
            return 0;
        }
    }
    return 1;
}
int main(){
    freopen("rebirth.in","r",stdin);
    freopen("rebirth.out","w",stdout);
    cin>>tt;
    while(tt--){
        cin>>n>>c;
        sd=0;
        for(int i=1;i<=n;i++){
            a[i].t=read();
            a[i].d=read();
            if(a[i].t%a[i].d==0){
                a[i].a=a[i].t/a[i].d;
            }
            else{
                a[i].a=a[i].t/a[i].d+1;
            }
            sd+=a[i].t; 
        }
        sort(a+1,a+n+1,cmp);
        long long l=1,r=(9e18)/c,md=1e18+7;
        while(l<=r){
            long long mid=(l+r)/2;
            if(abc(mid)==1){
                md=min(md,mid);
                r=mid-1;
            }
            else{
                l=mid+1;
            }
        }
        cout<<md-1<<endl;
    }
    return 0;
}

posted @ 2025-10-27 20:30  bz02_2023f2  阅读(2)  评论(0)    收藏  举报  来源