# ybtoj train passenger carrying problem (refined)

This question is very interesting. It took me 5h and finally came out under the siege of a crowd of big guys

## meaning of the title

The train with a passenger limit of c people passes through n stations. Now there are k stations. Each station has a group of people with the same starting point and the same end point. Now we need to maximize the number of people we can reach without overloading the passenger volume (it can be taken in different groups). What is the number of people

## Initial thinking

For each group of people, the line segment composed of starting point and ending point can be divided into starting point and ending point (nonsense). In this way, we can take all points offline, sort them according to time, and enumerate what will happen to the train at each station
So what happens on the train
First of all, there are two kinds of stops, one is getting on and the other is getting off
It's easy to get off. Just count the people getting off at this stop
The problem is getting in the car
There are two kinds of getting on the bus: one is free and the other is not free
It's easy when the car is free. Just plug it in as hard as you can
The problem is that the car is not free. At this time, we should consider whether the people we will add are better
So how is it better
Here we can consider an ancient topic: segment coverage
Think about how to do segment coverage. For a segment, we greedily make the right endpoint as small as possible, so that it will have less impact on the next selection and the final result will be better
Returning to this question, we can find that when some people get off earlier, they will have less impact on the back and the later results will be better. Because the number of upper and lower people is the same, our previous results will not be affected
Therefore, always select the one who gets off early and replace the one who gets off late with it, and the result will be better. Here we can use heap to achieve
But there is a problem here, that is to kick people off the train when they get there!

## Start code

```#include<bits/stdc++.h>
#define N 300005
#define ll long long
#define pqg(x) priority_queue<x,vector<x>,greater<x> >
#define pql(x) priority_queue<x>
#define fn(i,st,ed) for(int i=st;i<=ed;i++)
#define fd(i,st,ed) for(int i=st;i>=ed;i--)
#define pa pair<int,pair<int,pair<int,int> > >
#define mkp(x,y) make_pair(x,y)
using namespace std;
ll x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
struct train{int st,ed,num,id;}a[N];
struct Time{int time,id,op;}b[N];
pqg(train)q;
bool operator>(const train& a,const train& b){return a.ed>b.ed;}
bool operator<(const train& a,const train& b){return a.ed<b.ed;}
bool cmp(Time a,Time b){return a.time!=b.time?a.time<b.time:a.op>b.op;}
int main(){
a[i]=(train){s,t,p,0};
b[++time_tot]=(Time){s,i,0};
b[++time_tot]=(Time){t,i,1};
}
sort(b,b+time_tot+1,cmp);
fn(i,1,time_tot){int id=b[i].id;
if(b[i].op==0){
while(sum<c&&a[id].num){
}
while(!q.empty()&&a[id].num&&a[id]<q.top()){
while(!q.empty()&&q.top().ed<b[i].time)
a[q.top().id].id=0,q.pop();
if(q.empty())break;
train temp=q.top();q.pop();
if(temp.num)q.push(temp);
}
}else{
ans+=a[id].id;
sum-=a[id].id;
a[id].id=0;
}
}
printf("%d\n",ans);
return 0;
}

```

## Nightmare debug

It took about two hours to write the above code
Then the problems began to appear continuously. First, I overloaded the priority queue operator
In the future, we must remember that priority queue overloading is an operator in different directions of overloading and priority queue. A little trick is that you can overload both
You can get 60 points here, and the time is not very long, about half an hour or so
Real nightmares come
I started crazy debugging. First, I checked whether the quantities in the process were calculated correctly, and then straightened out my ideas again. It seemed that there was no problem
It's probably a whole point. It's probably right with the problem solution. It's really Bengbu. I decided to ask the boss for help
In the process of explaining my ideas to the boss, I noticed that there was something wrong. After the boss made it clear, I seemed to realize that there was a problem in my order of getting on and off. When passing through a key station, the first thing we should do is to check whether there were people getting off between the key stations. After that, we should first fill in the gap and then change

## 60 point code

```#include<bits/stdc++.h>
#define N 300005
#define ll long long
#define pqg(x) priority_queue<x,vector<x>,greater<x> >
#define pql(x) priority_queue<x>
#define fn(i,st,ed) for(int i=st;i<=ed;i++)
#define fd(i,st,ed) for(int i=st;i>=ed;i--)
using namespace std;
int x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
struct train{int st,ed,num,id;}a[N];
struct Time{int time,id,op;}b[N];
pqg(train)q;
bool operator>(const train& a,const train& b){return a.ed<b.ed;}
bool operator<(const train& a,const train& b){return a.ed<b.ed;}
bool cmp(Time a,Time b){return a.time!=b.time?a.time<b.time:a.op>b.op;}
signed main(){
a[i]=(train){s,t,p,0};
b[++time_tot]=(Time){s,i,0};
b[++time_tot]=(Time){t,i,1};
}
sort(b+1,b+time_tot+1,cmp);
fn(i,1,time_tot){int id=b[i].id;
if(b[i].op==0){
while(!q.empty()&&q.top().ed<b[i].time)
a[q.top().id].id=0,q.pop();
while(sum<c&&a[id].num){
}
while(!q.empty()&&a[id].num&&a[id]<q.top()){
if(q.empty())break;
train temp=q.top();q.pop();
if(temp.num)q.push(temp);
}
}else{
ans+=a[id].id;
sum-=a[id].id;
a[id].id=0;
}
}
printf("%d\n",ans);
return 0;
}

```

## Final completion

But after you hand in the above code, you still get 60 points. What's the problem
After a meal, I finally found it!!!
For calculating the total value, this while is meaningless. If it wants to join the team repeatedly, it can't join the team directly every time. Otherwise, it's basically invalid. It needs to count the total number of people on the bus, and then deal with it finally. In this way, it's successful
There is also a small colored egg here. The array should be opened to 6e5, because we remember the start and end points respectively, and the start and end points are 3e5 respectively, so the array must be opened to 6e5
You should also pay attention to the array. Recently, it is always wrong. You have to calculate it first before you can write it up

## Terminal code

```#include<bits/stdc++.h>
#define N 600005
#define ll long long
#define pqg(x) priority_queue<x,vector<x>,greater<x> >
#define pql(x) priority_queue<x>
#define fn(i,st,ed) for(int i=st;i<=ed;i++)
#define fd(i,st,ed) for(int i=st;i>=ed;i--)
using namespace std;
int x=0,f=1;char c=getchar();
while(!isdigit(c)){if(c=='-')f=-1;c=getchar();}
while(isdigit(c)){x=x*10+c-'0';c=getchar();}
return x*f;
}
struct train{int st,ed,num,id;}a[N];
struct Time{int time,id,op;}b[N];
pql(train)q;
bool operator<(const train& a,const train& b){return a.ed<b.ed;}
bool cmp(Time a,Time b){return a.time!=b.time?a.time<b.time:a.op>b.op;}
signed main(){
a[i]=(train){s,t,p,0};
b[++time_tot]=(Time){s,i,0};
b[++time_tot]=(Time){t,i,1};
}
sort(b+1,b+time_tot+1,cmp);
train temp;
fn(i,1,time_tot){int id=b[i].id;
//printf("%d %d %d %d %d %d %d %d\n",b[i].id,b[i].op,b[i].time,a[id].st,a[id].ed,a[id].num,a[id].id,sum);
if(b[i].op==0){
while(!q.empty()&&q.top().ed<=b[i].time)
a[q.top().id].id=0,q.pop();
while(sum<c&&a[id].num){
}
while(!q.empty()&&a[id].num&&a[id]<q.top()){
temp=q.top();q.pop();
if(temp.num)q.push(temp);
}
}else{
ans+=a[id].id;
sum-=a[id].id;
a[id].id=0;
}
}
printf("%d\n",ans);
return 0;
}

```

## One last point

Don't be credulous!

Tags: Algorithm

Posted on Tue, 07 Sep 2021 01:40:12 -0400 by MrQcue