This is the K question of CCPC Harbin. At that time, I heard that the THU card question girls team next door said that it was a 01 score plan, and I gave up before I learned it. Later, I found that this thing is quite stupid. I took out the BB today and quickly became AC.
The meaning of the question: Select a part of the interval from a bunch of [si, ti] to completely cover [1, T], each interval has two weights ai bi, and the selected interval is required to be
Practice: first refer to the article of fjzzq boss https://www.cnblogs.com/zzqsblog/p/5450361.html , find that the 01 fraction plan is to multiply the denominator after the two-point answer, so that
Code:
#include <bits/stdc++.h>
using namespace std;
const int maxn=100007;
int n, t;
struct node {
int s, t, a, b;
bool tag;
}rec[maxn];
bool cmp(node a, node b){
if(a.s==b.s)return a.t<b.t;
return a.s<b.s;
}
bool vis[maxn];
double c[maxn];
int lowbit(int x){
return x&(-x);
}
void update(int x, double num){
while(x){
c[x]=min(c[x], num);
x-=lowbit(x);
}
}
double query(int x){
if(x==0)return 0;
double ans=1e9;
while(x<=t){
ans=min(ans, c[x]);
x+=lowbit(x);
}
return ans;
}
bool check(double mid){
double sum=0;
int r=0;
for(int i=1;i<=t;i++){
c[i]=1e9;
}
for(int i=1;i<=n;i++){
if(rec[i].b*mid-rec[i].a>0){
sum+=rec[i].b*mid-rec[i].a;
rec[i].tag=true;
if(rec[i].s-1<=r){
r=max(r, rec[i].t);
}
}
else rec[i].tag=false;
}
if(r==t)return true;
update(r, 0);
for(int i=1;i<=n;i++){
if(!rec[i].tag){
double from=query(rec[i].s-1);
update(rec[i].t, from+rec[i].a-rec[i].b*mid);
}
else {
double from=query(rec[i].s-1);
update(rec[i].t, from);
}
}
return sum>=query(t);
}
int main(){
int T;
scanf("%d", &T);
while(T--){
scanf("%d%d", &n, &t);
for(int i=1;i<=n;i++){
scanf("%d%d%d%d", &rec[i].s, &rec[i].t, &rec[i].a, &rec[i].b);
}
sort(rec+1, rec+1+n, cmp);
double l=0, r=1001;
int tim=30;
for(int i=1;i<=tim;i++){
double mid=(l+r)/2;
if(check(mid))r=mid;
else l=mid;
}
printf("%.3f\n", l);
}
}