每次查找当前位置开始权值到结束权值之间最小时间,更新结束点的最小时间。
不过在建树的时候初始化写在if里面了,因此wrong了n次还蛋疼了一晚上。
ACcode:
#include<cstdio>
#include<iostream>
#include<algorithm>
using std::unique;
using std::sort;
typedef long long LL;
const int nsize=111111;
const LL INF=1000000000000000LL;
struct Item
{
int v,u,t;
bool operator < (const Item &cmp) const{
return v<cmp.v;
}
} item[nsize];
int X[nsize<<1];
LL sum[nsize<<3],t;
LL Min(LL a1,LL a2)
{
return a1<a2? a1:a2;
}
void build(int rt,int l,int r)
{
sum[rt]=INF;
if (l==r) return ;
int m=(l+r)>>1;
build(rt<<1,l,m);
build(rt<<1|1,m+1,r);
}
int Fin(int key,int len)
{
int l=0,r=len;
while (l<=r)
{
int m=(l+r)>>1;
if (X[m]==key) return m;
else if (X[m]<key) l=m+1;
else r=m-1;
}
return -1;
}
void update(int rt,int l,int r,int p,LL v)
{
if (l==r)
{
sum[rt]=Min(sum[rt],v);
return ;
}
int m=(l+r)>>1;
if (p<=m) update(rt<<1,l,m,p,v);
else update(rt<<1|1,m+1,r,p,v);
sum[rt]=Min(sum[rt<<1],sum[rt<<1|1]);
}
LL query(int rt,int l,int r,int L,int R)
{
if (L<=l&&r<=R) return sum[rt];
LL ans=INF;
int m=(l+r)>>1;
if (L<=m) ans=Min(ans,query(rt<<1,l,m,L,R));
if (R>m) ans=Min(ans,query(rt<<1|1,m+1,r,L,R));
return ans;
}
int main()
{
int T,top,cas=0;
int i,n,m,L,R;
scanf("%d",&T);
while (T--)
{
scanf("%d %d",&n,&m);
for (top=i=0; i<n; i++)
{
scanf("%d%d%d",&item[i].v,&item[i].u,&item[i].t);
X[top++]=item[i].v;
X[top++]=item[i].u;
}
X[top++]=m,X[top++]=1;
sort(X,X+top);
sort(item,item+n);
top=unique(X,X+top)-X-1;
build(1,0,top);
update(1,0,top,0,0);
printf("Case #%d: ",++cas);
for (i=0; i<n; i++)
{
if (item[i].u>=item[i].v) continue;
L=Fin(item[i].u,top);
R=Fin(item[i].v,top);
t=query(1,0,top,L,R-1);
if (t>=INF) continue;
update(1,0,top,R,t+(LL)item[i].t);
}
t=query(1,0,top,Fin(m,top),top);
if (t==INF) t=-1;
printf("%lld\n",t);
}
return 0;
}