用RMQ选取指定区间内的最小值
#include <iostream>
#include <cstdio>
#include <cmath>
#include <queue>
#include <vector>
#include <algorithm>
#include <cmath>
#include <memory.h>
using namespace std;
typedef long long ll;
ll num[] = {0,31,59,90,120,151,181,212,243,273,304,334,365};
ll t,s,n,m;
ll c[100050];
ll INF = 1 << 30;
ll d[100050][17];
class Node
{
public :
char mon[5];
ll day,year,hour,r,sumhour,month;
ll cost;
public:
bool getyear(int y)
{
if((y %4 == 0 && y % 100 != 0)||(y % 400 == 0))
return true;
else
return false;
}
ll getyearsday()
{
ll sum = 0;
for(int i = 2000;i < year;i++)
{
if(getyear(i)) sum += 366;
else sum += 365;
}
return sum;
}
ll getmonth()
{
if(mon[0] == 'J')
{
if(mon[1] == 'a')return 1;
else if(mon[1] == 'u')
{
if(mon[2] == 'n')return 6;
else return 7;
}
}
else if(mon[0] == 'F')return 2;
else if(mon[0] == 'M')
{
if(mon[2] == 'r')return 3;
else return 5;
}
else if(mon[0] == 'A')
{
if(mon[1] == 'p')return 4;
else return 8;
}
else if(mon[0] == 'S') return 9;
else if(mon[0] == 'O')return 10;
else if(mon[0] == 'N')return 11;
else if(mon[0] == 'D')return 12;
}
ll getday()
{
ll sum = getyearsday();
if(!getyear(year))
{
sum += num[month -1];
sum += day;
}
else
{
if(month <= 2)
{
sum += num[month-1];
sum += day;
}
else
{
sum += num[month -1]+1;
sum += day;
}
}
return sum - 1;
}
ll gethour()
{
ll sum = getday() * 24;
sum += hour;
return sum;
}
void getcost()
{
if(sumhour - t > 1)
{
ll k = ll(log(t+1)/log(2));
ll tmp = ll(pow(2.0,int(k)));
cost = min(d[sumhour-t][k],d[sumhour - tmp + 1][k]);
}
else
{
ll k = ll(log(sumhour) / log(2));
ll tmp = ll(pow(2.0,int(k)));
cost = min(d[1][k],d[sumhour-tmp + 1][k]);
}
cost = (cost + sumhour * s)*r;
return;
}
void init()
{
month = getmonth();
sumhour = gethour()+1;
}
}node[2505];
int main()
{
INF = INF * INF;
while(scanf("%I64d%I64d",&n,&m)!=EOF &&(n && m))
{
for(ll i = 1;i <= n;i++)
{
scanf("%s",&node[i].mon);
scanf("%I64d%I64d%I64d%I64d",&node[i].day,&node[i].year,&node[i].hour,&node[i].r);
node[i].init();
}
scanf("%I64d%I64d",&t,&s);
ll ans = 0;
for(ll i = 1;i <= m;i++)
{
scanf("%I64d",&c[i]);
c[i] -= i*s;
}
memset(d,0,sizeof(d));
for(ll i = 1;i <= m;i++)d[i][0] = c[i];
for(ll i = 1;i <=ll(log(m)/log(2));i++)
{
for(ll j = 1;j <= m;j++)
{
d[j][i] = d[j][i-1];
ll tmp = ll(pow(2.0,int(i-1)));
if(j + tmp <= m && d[j+tmp][i-1] < d[j][i])
d[j][i] = d[j+tmp][i-1];
}
}
for(ll i = 1;i <= n;i++)
{
node[i].getcost();
ans += node[i].cost;
}
//cout << ans << endl;
printf("%I64d\n",ans);
}
return 0;
}