题意:star开始有1元的东西,有N种交易,每种交易Vi,Ri,Ti表示用至少Ri的东西去换得Vi的东西,这个过程要求的时候是Ti。问最后得到至少M元的东西,如果能得到花费的最少的时间是多少。
在线段树的每个叶子结点ai里用mi表示交换到价值为ai的物品所需要的最少时间。对每个交易,按可以交易的最小金额(就是Ri)从小到大排序,接下来可以全是线段树的操作。
对于每个交易,我们查询[Ri,Ti-1]里所有花费时间最小的,然后去更新Ti这个点的最小时间mi。当然,线段树里所有结点的mi都必须先更新为无穷大INF。
#include <iostream> #include <cstdio> #include <cstring> #include <map> #include <algorithm> #include <vector> using namespace std; typedef long long LL; #define LL(x) (x<<1) #define RR(x) (x<<1|1) #define MID(a,b) (a+((b-a)>>1)) #define INF ((LL)1<<60) const int N=200005; struct Op { int ed,st,valu; void get() {scanf("%d%d%d",&ed,&st,&valu);} bool operator<(const Op &b)const { return st<b.st; } }op[N/2]; struct node { LL mi; int lft,rht; int mid(){return MID(lft,rht);} }; int n,m; vector<int> y; map<int,int> H; struct Segtree { node tree[N*4]; void build(int lft,int rht,int ind) { tree[ind].lft=lft; tree[ind].rht=rht; tree[ind].mi=INF; if(lft!=rht) { int mid=tree[ind].mid(); build(lft,mid,LL(ind)); build(mid+1,rht,RR(ind)); } } void updata(int pos,int ind,LL valu) { if(tree[ind].lft==tree[ind].rht) tree[ind].mi=valu; else { int mid=tree[ind].mid(); if(pos<=mid) updata(pos,LL(ind),valu); else updata(pos,RR(ind),valu); tree[ind].mi=min(tree[LL(ind)].mi,tree[RR(ind)].mi); } } LL query(int st,int ed,int ind) { int lft=tree[ind].lft,rht=tree[ind].rht; if(st<=lft&&rht<=ed) return tree[ind].mi; else { int mid=tree[ind].mid(); LL mi1=INF,mi2=INF; if(st<=mid) mi1=query(st,ed,LL(ind)); if(ed> mid) mi2=query(st,ed,RR(ind)); return min(mi1,mi2); } } }seg; int main() { int t,t_cnt=0; scanf("%d",&t); while(t--) { y.clear(); H.clear(); scanf("%d%d",&n,&m); y.push_back(1); y.push_back(m); for(int i=0;i<n;i++) { op[i].get(); y.push_back(op[i].st); y.push_back(op[i].ed); } sort(op,op+n); sort(y.begin(),y.end()); y.erase(unique(y.begin(),y.end()),y.end()); for(int i=0;i<(int)y.size();i++) H[y[i]]=i; seg.build(0,(int)y.size()-1,1); seg.updata(H[1],1,0); for(int i=0;i<n;i++) { int st=H[op[i].st],ed=H[op[i].ed],valu=op[i].valu; LL mi=seg.query(st,ed-1,1); seg.updata(ed,1,mi+valu); } LL res=seg.query(H[m],(int)y.size()-1,1); printf("Case #%d: ",++t_cnt); if(res<INF) printf("%lld\n",res); else puts("-1"); } return 0; }