hdu 单调队列

题目链接:http://acm.hdu.edu.cn/showproblem.php?pid=4122

 

代码:

#include<cstdio>
#include<iostream>
#include<algorithm>
#include<cstring>
#include<map>
#include<string>
using namespace std;

const int maxn = 100500;

struct Node
{
    int id,val;
};

int order[2555];
long long R[2555];
int S,T,N,M;


struct Myqueue
{
    Node Q[maxn];
    int head,tail;

    void init()
    {
        head = tail = 0;
    }

    void push(int id,int val)
    {
        while(head < tail && Q[tail-1].val+S*(id-Q[tail-1].id) >= val)  
            tail--;
        Q[tail].val = val;
        Q[tail++].id = id;
    }

    void pop(int id)
    {
        while(head < tail && Q[head].id < id - T)  //单调区间的最小值。
            head++;
    }

    Node getfront()
    {
        return Q[head];
    }
}solver;

map<string,int> mymap;

void init()
{
    mymap["Jan"] = 1;  mymap["Feb"] = 2;  mymap["Mar"] = 3;
    mymap["Apr"] = 4;  mymap["May"] = 5;  mymap["Jun"] = 6;
    mymap["Jul"] = 7;  mymap["Aug"] = 8;  mymap["Sep"] = 9;
    mymap["Oct"] = 10; mymap["Nov"] = 11; mymap["Dec"] = 12;
}

int mou[13] = {0,31,28,31,30,31,30,31,31,30,31,30,31};
void GetOrder()
{
    string s;
    int date,year,H;

    for(int i=1; i<=N; i++)
    {
        cin>>s;
        scanf("%d %d %d %I64d",&date,&year,&H,&R[i]);
        int mouth = mymap[s];
        year -= 2000;
        order[i] = (365*4+1)*(year/4);
        year = year%4;
        if(year == 0)
        {
            for(int j=1; j<mouth; j++)
            {
                order[i] += mou[j];
                if(j == 2) order[i] += 1;
            }
        }
        else
        {
            order[i] += 366 + (year-1)*365;
            for(int j=1; j<mouth; j++)
                order[i] += mou[j];
        }
        order[i] += date - 1;
        order[i] = order[i]*24 + H + 1;
    }
}
int main()
{
    //freopen("E:\\acm\\input.txt","r",stdin);
    init();
    while(cin>>N>>M && N+M)
    {
        GetOrder();

        scanf("%d %d",&T,&S);
        solver.init();

        int cnt = 1;
        long long ans = 0;
        for(int i=1; i<=M; i++)
        {
            int cost;
            scanf("%d",&cost);

            solver.push(i,cost);
            solver.pop(i);         //先去掉过期的

            Node cur = solver.getfront();
            while(order[cnt] == i && cnt <= N)  //cnt的上限,和while循环,考虑了,为啥不加。
            {
                ans += (cur.val + (i-cur.id)*S ) * R[cnt];  //乘法溢出问题
                cnt ++;
            }
        }
        printf("%I64d\n",ans);
    }
}
View Code

 

posted @ 2013-10-24 22:40  等待最好的两个人  阅读(174)  评论(0编辑  收藏  举报