这道题暴力竟然比标程跑的快!!!!
在这里RMQ维护的是一段区间内最小代价的下标。
另外就是注意一下 求某两天之间有多少天的函数怎么写。
感觉这道题没做出来一个是题没读懂,第二个就是不敢去暴,第三个就是对一些问题的转化不够。
#include<set>
#include<map>
#include<cmath>
#include<vector>
#include<cstdio>
#include<cstring>
#include<iostream>
using namespace std;
typedef long long LL;
const LL INF = (1LL << 62);
const int days = 365;
const int s[] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
int Isleap(int y){
if(y % 400 == 0 || y % 100 && y % 4 == 0) return 1;
return 0;
}
int leap(int y){
if(!y) return 0;
return y / 4 - y / 100 + y / 400;
}
int calc(int day,int mon,int year){
int res = (year - 1) * days + leap(year - 1);
for(int i = 1; i < mon; i++)
res += s[i];
if(Isleap(year) && mon > 2) res ++;
res += day;
return res;
}
int count_day(int da,int ma,int ya,int db,int mb,int yb){
int resa = calc(da,ma,ya);
int resb = calc(db,mb,yb);
return abs(resa - resb);
}
//
int N,M,T,S;
int cost[100005];
struct Data{
int hour,num;
}data[2505];
//
int judgeMonth(char *s){
if(strcmp(s,"Jan") == 0) return 1;
if(strcmp(s,"Feb") == 0) return 2;
if(strcmp(s,"Mar") == 0) return 3;
if(strcmp(s,"Apr") == 0) return 4;
if(strcmp(s,"May") == 0) return 5;
if(strcmp(s,"Jun") == 0) return 6;
if(strcmp(s,"Jul") == 0) return 7;
if(strcmp(s,"Aug") == 0) return 8;
if(strcmp(s,"Sep") == 0) return 9;
if(strcmp(s,"Oct") == 0) return 10;
if(strcmp(s,"Nov") == 0) return 11;
if(strcmp(s,"Dec") == 0) return 12;
}
//RMQ
int dp[100005][30];
int minv(int i,int j){
if(i == j) return i;
if(i < j){
if((j - i) * S >= cost[j] - cost[i])
return j;
else
return i;
}
else{
if((i - j) * S >= cost[i] - cost[j])
return i;
else
return j;
}
}
void RMQ_Init(){
for(int i = 0; i < M; i++) dp[i][0] = i;
for(int j = 1; (1 << j) <= M; j++)
for(int i = 0; i + (1 << j) - 1 < M; i++)
dp[i][j] = minv(dp[i][j - 1],dp[i + (1 << (j - 1))][j - 1]);
}
int Query(int L,int R){
int k = 0;
while((1 << (k + 1)) <= R - L + 1)
k ++;
return minv(dp[L][k],dp[R - (1 << k) + 1][k]);
}
//
int main(){
while(scanf("%d%d",&N,&M) != EOF){
if(!N && !M) break;
char mm[50];
int day,year,hour,num;
for(int i = 0; i < N; i++){
scanf("%s%d%d%d%d",
mm,&day,&year,
&hour,&num);
data[i].hour = count_day(1,1,2000,day,judgeMonth(mm),year) * 24 + hour;
data[i].num = num;
}
scanf("%d%d",&T,&S);
for(int i = 0; i < M; i++)
scanf("%d",&cost[i]);
LL ans = 0;
RMQ_Init();
for(int i = 0; i < N; i++){
int l = data[i].hour - T + 1;
int r = data[i].hour;
if(l < 0) l = 0;
if(r >= M) r = M - 1;
int pos = Query(l,r);
//printf("%d\n",pos);
ans += ((LL)(cost[pos] + S * (data[i].hour - pos)) * data[i].num);
}
printf("%I64d\n",ans);
}
return 0;
}