Southern Subregion Problem F. Judging Time Prediction

本文探讨了在ACM-ICPC等编程比赛中预测单一提交的判题时间问题。假设存在包含n个测试用例的问题集,每个测试用例都有预估的判题时间和通过概率。文章提供了一个算法,用于计算在特定条件下,根据可用的m台判题机器来预测判题过程结束的期望时间。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

Problem F. Judging Time Prediction
Input le: stdin Output le: stdout Time limit: 2 seconds Memory limit: 256 megabytes Feedback:
It is not easy to predict. Do you know that the modern weather prediction is marginally better than to use the previous day weather as a prediction for the next day? This problem is about judging a submission on a programming contest like ACM-ICPC. Suppose there is a single submission for the problem containing n tests. Based on the previous statistics for each test we know ti the expected time to judge on it and pi the probability of a submission to pass the test. There are m judging machines in the system. They are completely independent and are used to judge a submission on multiple tests at the same time. They work as follows. Each time a judging machine has no task (has just started or nished processing the previous job), it chooses the unprocessed test with the smallest number and judges submission on the chosen test. If it was judged on the i-th test, then after time ti the verdict will be known. As it was written above, the probability that a submission passes the test is pi. Let's assume that the judging process starts at the same moment when all the judging machines start. So at this moment the rst min(m,n) tests start on the judging machines. You know that on ACM-ICPC contests it is not necessary to judge a submission on all tests. The judging process will be aborted at the rst moment when two conditions are met at the same time:
• the solution was judged on some test (say, x) and didn't pass it, • the solution was judged on all the tests 1,2,...,x−1 and passed all of them.
Naturally, if all the tests are judged and passed the judging process ends too. Write a program to print the expected time to judge a submission. It means that you are to nd the mathematical expectation of the judging time according to the specied model.
Input The rst line of the input contains two integer numbers n and m (1 6 n 6 3·105,1 6 m 6 3·105) the number of tests and judging machines. The following n lines contain pairs of integers ti and real numbers pi (1 6 ti 6 100,0 < pi < 1), where ti is the time required to judge the i-th test and pi is the probability to pass the i-th test. The values pi are given with no more than 4 digits after the decimal point.
Output
Print the only real number e the expected time to judge the submission. Print it with at least 4 digits after the decimal point.
Examples
stdin stdout
2 1 1 0.5 2 0.5
2.0000000000
2 2 1 0.5 2 0.5
1.5000000000

#include <iostream>
#include <cstdio>
#include <cstring>
#define lson rt<<1,l,mid
#define rson rt<<1|1,mid+1,r
#define maxn 300005
using namespace std;
int n,m;
int t[maxn];
double p[maxn];
int num[maxn];
struct Node{
		//int val;
		int minn;
		int maxx;
		int min_whe;
		int flag;
}tree[maxn * 4];
int root = 1;
void push_up(int rt){
		tree[rt].minn = min(tree[rt<<1].minn,tree[rt<<1|1].minn);
		tree[rt].min_whe = (tree[rt<<1].minn <= tree[rt<<1|1].minn) ? tree[rt<<1].min_whe : tree[rt<<1|1].min_whe;
		tree[rt].maxx = max(tree[rt<<1].maxx,tree[rt<<1|1].maxx);
}
void push_down(int rt){
		if(tree[rt].flag){
				tree[rt<<1].minn += tree[rt].flag;
				tree[rt<<1].maxx += tree[rt].flag;
				tree[rt<<1].flag += tree[rt].flag;
				tree[rt<<1|1].minn += tree[rt].flag;
				tree[rt<<1|1].maxx += tree[rt].flag;
				tree[rt<<1|1].flag += tree[rt].flag;
				tree[rt].flag = 0;
		}
}
void build(int rt,int l,int r){
		if(l == r) {
				tree[rt].min_whe = l;
				return;
		}
		int mid = (l+r) >> 1;
		build(lson);
		build(rson);
		push_up(rt);
}
void update(int L,int R,int key,int rt,int l,int r){
		if(l > R || r < L) return;
		if(L <= l && r <= R){
				tree[rt].minn += key;
				tree[rt].maxx += key;
				tree[rt].flag += key;
				return;
		}
		int mid = (l+r) >> 1;
		push_down(rt);
		update(L,R,key,lson);
		update(L,R,key,rson);
		push_up(rt);
}
int query(int L,int R,int rt,int l,int r){
		if(l > R || r < L) return 0x3f3f3f3f;
		if(L <= l && r <= R){
				return tree[rt].minn;
		}
		int mid = (l+r)>>1;
		push_down(rt);
		int ans = query(L,R,lson);
		ans = min(ans,query(L,R,lson));
		push_up(rt);
		return ans;
}
int time_now;
int time_tot;
double ans;
double pre = 1;
int main(){
		//freopen("main.in","r",stdin);
		cin >> n >> m;
		for(int i = 1; i <= n; i++) {
				cin >> t[i] >> p[i];
		}
		build(1,1,m);
		for(int i = 1; i <= n; i++) {
				int minn = query(1,m,1,1,m);
				update(1,n,-minn,1,1,m);
				time_now += minn;
				int whe = tree[root].min_whe;
				update(whe,whe,t[i],1,1,m);
				time_tot = time_now + tree[root].maxx;
				double p_now = pre * (1 - p[i]);
				ans += time_tot * p_now;
				pre *= p[i];
				if(i == n) {
						ans += time_tot * pre;
				}
		}
		printf("%.10lf\n",ans);
		return 0;
}

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值