【u118】日志分析

Time Limit: 1 second
Memory Limit: 128 MB

【问题描述】

M 海运公司最近要对旗下仓库的货物进出情况进行统计。目前他们所拥有的唯一记录就是一个记录集装箱进出情况的日志。该日志记录了两类操
作:第一类操作为集装箱入库操作,以及该次入库的集装箱重量;第二类操作为集装箱的出库操作。这些记录都严格按时间顺序排列。集装
箱入库和出库的规则为先进后出,即每次出库操作出库的集装箱为当前在仓库里所有集装箱中最晚入库的集装箱。
出于分析目的,分析人员在日志中随机插入了若干第三类操作——查询操作。分析日志时,每遇到一次查询操作,都要报告出当前仓库中最大集
装箱的重量。

【输入格式】

输入文件log.in包含N+1 行:
第一行为1 个正整数N,对应于日志内所含操作的总数。
接下来的N 行,分别属于以下三种格式之一:
格式1: 0 X //一次集装箱入库操作,正整数X表示该次入库的集装箱的重量
格式2: 1 //一次集装箱出库操作,(就当时而言)最后入库的集装箱出库
格式3: 2 //一次查询操作,要求分析程序输出当前仓库内最大集装箱的重量
当仓库为空时你应该忽略出库操作,当仓库为空查询时你应该输出0。

【输出格式】

输出文件log.out输出行数等于日志中查询操作的次数。每行为一个正整数,表示查询结果。

【数据规模】

对于20%的数据,有N≤10; 对于40%的数据,有N≤1000; 对于100%的数据,有N≤200000,X≤10^8。

Sample Input1

13
0 1
0 2
2
0 4
0 2
2
1
2
1
1
2
1
2

Sample Output1

2
4
4
1
0

【题目链接】:http://noi.qz5z.com/viewtask.asp?id=u118

【题解】

解法①:因为只涉及到一个数据的插入和删除,所以用堆来维护栈中元素的最大值;要记录栈中某个元素在堆中的位置;
解法②设f[i]表示栈中从下往上数i个元素中的最大值是什么,进栈的时候f[++top]=max(f[top-1],x);查询直接输出f[top];
(解法②自己写,下面只有解法①的代码);

【完整代码】

#include <cstdio>
#include <cstdlib>
#include <cmath>
#include <set>
#include <map>
#include <iostream>
#include <algorithm>
#include <cstring>
#include <queue>
#include <vector>
#include <stack>
#include <string>
using namespace std;
#define lson l,m,rt<<1
#define rson m+1,r,rt<<1|1
#define LL long long
#define rep1(i,a,b) for (int i = a;i <= b;i++)
#define rep2(i,a,b) for (int i = a;i >= b;i--)
#define mp make_pair
#define pb push_back
#define fi first
#define se second

typedef pair<int,int> pii;
typedef pair<LL,LL> pll;

void rel(LL &r)
{
    r = 0;
    char t = getchar();
    while (!isdigit(t) && t!='-') t = getchar();
    LL sign = 1;
    if (t == '-')sign = -1;
    while (!isdigit(t)) t = getchar();
    while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
    r = r*sign;
}

void rei(int &r)
{
    r = 0;
    char t = getchar();
    while (!isdigit(t)&&t!='-') t = getchar();
    int sign = 1;
    if (t == '-')sign = -1;
    while (!isdigit(t)) t = getchar();
    while (isdigit(t)) r = r * 10 + t - '0', t = getchar();
    r = r*sign;
}

const int MAXN = 2e5+100;
const int dx[9] = {0,1,-1,0,0,-1,-1,1,1};
const int dy[9] = {0,0,0,-1,1,-1,1,-1,1};
const double pi = acos(-1.0);

struct abc
{
    int x,fro;
};

int n,zdz[MAXN],top=0,pos,dgd0=0;
abc dgd[MAXN];

void up_a(int p)
{
    int j = p/2,i=p;
    abc temp = dgd[p];
    while (j > 0)
    {
        if (temp.x>dgd[j].x)
        {
            dgd[i] = dgd[j];
            zdz[dgd[j].fro] = i;
            i = j;j=i/2;
        }
        else
            break;
    }
    dgd[i] = temp;
    zdz[temp.fro] = i;
    pos = i;
}

void do_a(int p)
{
    int i = p,j = i*2;
    abc temp = dgd[p];
    while (j <= dgd0)
    {
        if (j+1<=dgd0 && dgd[j+1].x>dgd[j].x)
            j++;
        if (temp.x<dgd[j].x)
        {
            dgd[i] = dgd[j];
            zdz[dgd[j].fro] = i;
            i = j,j = i*2;
        }
        else
            break;
    }
    dgd[i] = temp;
    zdz[temp.fro] = i;
    pos = i;
}

int main()
{
    //freopen("F:\rush.txt","r",stdin);
    rei(n);
    rep1(i,1,n)
    {
        int p;
        scanf("%d",&p);
        if (p==0)
        {
            int x;
            scanf("%d",&x);
            top++;
            dgd0++;
            abc temp;
            temp.x = x,temp.fro = top;
            dgd[dgd0] = temp;
            zdz[top] = dgd0;
            up_a(dgd0);
            do_a(pos);
        }
        else
            if (p==1)
            {
                if (top>0)
                {
                    int po = zdz[top];
                    dgd[po] = dgd[dgd0];
                    zdz[dgd[dgd0].fro] = po;
                    dgd0--;
                    up_a(po);
                    do_a(pos);
                    top--;
                }
            }
            else
                if (p==2)
                {
                    if (top>0)
                        printf("%d
",dgd[1].x);
                    else
                        puts("0");
                }
    }
    return 0;
}
原文地址:https://www.cnblogs.com/AWCXV/p/7626911.html