【HDU 4122】RMQ

来源:互联网 发布:手机测分软件 编辑:程序博客网 时间:2024/06/05 11:47

这道题暴力竟然比标程跑的快!!!!

在这里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;}//RMQint 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;}

0 0