勉强归类到线段树里面吧
先求出每个订单对应的时间点存入time
data[k].min 存储当前位置做月饼保存到最后一个订单的花费
然后线段树从第n个订单到第1个订单, 搜区间 【 time[n]-t ,time[n] 】 即可
#include "stdio.h"
#include "string.h"
#include "math.h"
#include "stdlib.h"
struct comp
{
int l,r,mid;
__int64 min;
} data[500010];
int dayy[13]={0,31,28,31,30,31,30,31,31,30,31,30,31};
int count[100010];
int time[100010];
__int64 s,a[100010];
int t,n;
int judge(int w)
{
if ((w%4==0 && w%100!=0) || w%400==0) return 1;
else return 0;
}
__int64 minn(__int64 x,__int64 y)
{
if (x<y) return x;
else return y;
}
int find_time(char str[10],int day,int year,int hour)
{
int ans,i,month;
ans=0;
for (i=2000;i<year;i++)
if (judge(i)==1) ans+=366*24;
else ans+=365*24;
if (strcmp(str,"Jan")==0) month=1;
if (strcmp(str,"Feb")==0) month=2;
if (strcmp(str,"Mar")==0) month=3;
if (strcmp(str,"Apr")==0) month=4;
if (strcmp(str,"May")==0) month=5;
if (strcmp(str,"Jun")==0) month=6;
if (strcmp(str,"Jul")==0) month=7;
if (strcmp(str,"Aug")==0) month=8;
if (strcmp(str,"Sep")==0) month=9;
if (strcmp(str,"Oct")==0) month=10;
if (strcmp(str,"Nov")==0) month=11;
if (strcmp(str,"Dec")==0) month=12;
for (i=1;i<month;i++)
if (i==2 && judge(year)==1) ans+=29*24;
else ans+=dayy[i]*24;
ans+=(day-1)*24;
ans+=hour;
return ans;
}
void build(int l,int r,int k)
{
data[k].l=l;
data[k].r=r;
data[k].mid=(l+r)/2;
if (l==r)
{
data[k].min=a[l]+s*(time[n]-l);
return ;
}
build(l,data[k].mid,k*2);
build(data[k].mid+1,r,k*2+1);
if (data[k*2].min<data[k*2+1].min) data[k].min=data[k*2].min;
else data[k].min=data[k*2+1].min;
}
__int64 search(int l,int r,int k)
{
if (data[k].l==l && data[k].r==r)
return data[k].min;
if (r<=data[k].mid) return search(l,r,k*2);
else
if (l>data[k].mid) return search(l,r,k*2+1);
else
return minn(search(l,data[k].mid,k*2),search(data[k].mid+1,r,k*2+1));
}
int main()
{
__int64 ans;
int m,i;
int day,year,hour;
__int64 min,ll;
char str[20];
while (scanf("%d%d",&n,&m)!=EOF)
{
if (n==0 && m==0) break;
for (i=1;i<=n;i++)
{
scanf("%s%d%d%d%d",str,&day,&year,&hour,&count[i]);
time[i]=find_time(str,day,year,hour);
}
scanf("%d%I64d",&t,&s);
for (i=0;i<m;i++)
scanf("%I64d",&a[i]);
build(0,m-1,1);
ans=0;
for (i=n;i>=1;i--)
{
ll=time[i]-t;
if (ll<0) ll=0;
min=search(ll,time[i],1);
ll=(time[n]-time[i])*s*count[i];
ans+=(min*count[i])-ll;
}
printf("%I64d\n",ans);
}
return 0;
}