题目 3189: 蓝桥杯2023年第十四届省赛真题-小蓝的旅行计划
参考代码
package 蓝桥__真题__专题;
import java.io.*;
import java.util.ArrayList;
import java.util.Map;
import java.util.PriorityQueue;
public class _2023试题G_小蓝的旅行计划01 {
private static int n,m,ans;
private static int maxn = 200005,vol = 0;
private static int Dis[],Cost[],Lim[],Rest[],k[];
static BufferedReader br = new BufferedReader(new InputStreamReader(System.in));
static StreamTokenizer st = new StreamTokenizer(br);
static int nextInt() throws Exception {st.nextToken();return (int) st.nval;}
static PrintWriter pw = new PrintWriter(new OutputStreamWriter(System.out));
public static void main(String[] args) throws Exception {
int ans = 1;
n = nextInt();
m = nextInt();
PriorityQueue<gas> q = new PriorityQueue<>();
Dis = new int[n+2];
Cost = new int[n+2];
Lim = new int[n+2];
Rest = new int[n+2];
k = new int[n+2];
for (int i=1;i<=n;i++){
Dis[i] = nextInt();
Cost[i] = nextInt();
Lim[i] = nextInt();
}
build(1,1,n);
for (int i=1;i<=n;i++){
vol -= Dis[i];
while (vol < 0){
if (q.isEmpty()){
pw.println(-1);
return;
}
gas remind = q.poll();
int cnt = Math.min(m-query(1,1,n,remind.id,i-1),Lim[remind.id]);
if (cnt <= 0){
continue;
}
if (cnt <= -vol){
ans += remind.c *cnt;
vol += cnt;
Lim[remind.id] = 0;
add(1,1,n,remind.id,i-1,cnt);
}else{
ans += remind.c *(-vol);
Lim[remind.id] = cnt +vol;
q.add(new gas(remind.id, remind.c));
vol = 0;
}
}
if (vol>0){
add(1,1,n,i,i,vol);
Lim[i] = Math.min(Lim[i],m-vol);
q.add(new gas(i,Cost[i]));
}
pw.println(ans);
}
pw.flush();
}
private static void add(int i, int l, int r, int ll, int rr, int v) {
if (ll <=1 && r<=rr){
Rest[i]+=v;
k[i]+=v;
return;
}
pd(i);
int mid = (l+(r-l)/2);
if (mid >=ll){
add(i<<1,l,mid,ll,rr,v);
}
if (mid<rr){
add(i<<1|1,mid+1,r,ll,rr,v);
}
up(i);
}
private static void pd(int i) {
if(k[i]!=0) {
k[i<<1] += k[i]; k[i<<1|1] += k[i];
Rest[i<<1] += k[i]; Rest[i<<1|1] +=k[i];
k[i] = 0;
}
}
private static void up(int i) {
}
private static int query(int i, int l, int r, int ll, int rr) {
if (ll <=l && r<=rr){
return Rest[i];
}
pd(i);
int res = 0;
int mid = (l+(r-l)/2);
if (mid>=ll){
res = Math.max(res,query(i<<1,l,mid,ll,rr));
}
if (mid<rr){
res = Math.max(res,query(i<<1,l,mid,ll,rr));
}
up(i);
return res;
}
private static void build(int i, int l, int r) {
if(l == r) {
Rest[i]=0;
return ;
}
int mid = (l+r)/2;
build(i<<1,l,mid);build(i<<1|1,mid+1,r);
up(i);
}
private static class gas implements Comparable<gas>{
long c;
int id;
public gas(int i,long a){
c = a;id = i;
}
@Override
public int compareTo(gas o) {
return this.c-o.c >0 ? 1:-1;
}
}
}