hdu 4122 Alice's mooncake shop(线段树RMQ)

来源:互联网 发布:js iso时间格式 编辑:程序博客网 时间:2024/05/16 08:58

设在时间t有一个订单,要N个月饼,每个月饼每小时储存话费为S,设i时刻的制作单价为Vi,那么在i时刻(i>=t-T)去制作的花费为Vi*N+(T-i)*S*N

变形一下变成T*S*N+N*(Vi-i*S),这个等式中只有Vi-i*S和i的选取有关,所以实际上就是要找出在t[i]到t[i]-T范围内最大的Vi-i*S即可。用线段树实现。


算时间时一定要仔细写,把dec写成dev WA了 N次!


代码:

#include <iostream>#include <cstdio>#include <cstring>using namespace std;#define maxn 100005#define lson l,m,rt<<1#define rson m+1,r,rt<<1|1#define INF 10000000#define LL long longLL V[maxn];LL Min[maxn<<2];LL Ord[maxn];LL t[maxn];int N,M,T,S;void pushup(int rt){    Min[rt]=min(Min[rt<<1],Min[rt<<1|1]);}void build(int l,int r,int rt){    if(l==r){        Min[rt]=V[l];        return;    }    int m=(l+r)>>1;    build(lson);    build(rson);    pushup(rt);}LL query(int L,int R,int l,int r,int rt){    if(L<=l&&R>=r) return Min[rt];    int m=(l+r)>>1;    LL res=10000000;    if(m>=L) res=min(res,query(L,R,lson));    if(m<R) res=min(res,query(L,R,rson));    return res;}bool isleapyear(int n){    return n % 4 == 0 && n % 100 != 0 || n % 400 == 0;    }LL Time(char *m, int d, int y, int h){    LL res=0;    for(int i=2000; i<y; i++){        if(isleapyear(i)) res += 366 * 24;        else res += 365 * 24;    }    if(strcmp(m,"Jan")==0) res+=0;    else if(strcmp(m,"Feb")==0) res+=31*24;    else if(strcmp(m,"Mar")==0) res+=59*24;    else if(strcmp(m,"Apr")==0) res+=90*24;    else if(strcmp(m,"May")==0) res+=120*24;    else if(strcmp(m,"Jun")==0) res+=151*24;    else if(strcmp(m,"Jul")==0) res+=181*24;    else if(strcmp(m,"Aug")==0) res+=212*24;    else if(strcmp(m,"Sep")==0) res+=243*24;    else if(strcmp(m,"Oct")==0) res+=273*24;    else if(strcmp(m,"Nov")==0) res+=304*24;    else if(strcmp(m,"Dec")==0) res+=334*24;        res+=(d-1)*24;    res+=h+1;    if((isleapyear(y))&&(strcmp(m,"Jan")!=0)&&(strcmp(m,"Feb")!=0)){        res+=24;    }    return res;}int main(){    while(~scanf("%d%d",&N,&M)){        if(!N&&!M) break;        for(int i=1;i<=N;i++){            char month[10];            int d,y,h,o;            scanf("%s%d%d%d%d",month,&d,&y,&h,&o);            t[i]=Time(month,d,y,h);            Ord[i]=o;        }        scanf("%d%d",&T,&S);        for(int i=1;i<=M;i++){            int tmp;            scanf("%d",&tmp);            V[i]=tmp-i*S;        }        build(1,M,1);        LL res=0;        for(int i=1;i<=N;i++){            LL s=(t[i]-T)>=1?(t[i]-T):1;            if((t[i]-T)>M) continue;            LL tmp=query(s,t[i],1,M,1);            res+=(tmp+t[i]*S)*Ord[i];        }        printf("%I64d\n",res);    }    return 0;}

0 0
原创粉丝点击