XDU-1156 等待队列 (线段树||单调队列)

来源:互联网 发布:dojo.js提示缺少对象 编辑:程序博客网 时间:2024/05/17 04:34
此处有目录↑

1156: 等待队列

时间限制: 1 Sec  内存限制: 128 MB
http://acm.xidian.edu.cn/problem.php?id=1156
[提交][状态][讨论版]

题目描述

输入

输出

对于每个第 类操作,输出 行,表示队列中所有人不耐烦程度的最大值。

样例输入

81 51 51 53231 203

样例输出

8921

解法一:线段树

比赛时一眼看出线段树能做,特别激动,第一次用上线段树了...

线段树维护区间最大值即可

初始化一个区间为[1,n]的线段树,操作1在点tail处添加,操作2直接修改查询区间(head++)即可,操作3直接查询[head,n]的区间最大值


看了题解以后发现可以用单调队列写,暂时先放着吧...

#include <cstdio>#include <algorithm>#define lson (i<<1)#define rson ((i<<1)|1)using namespace std;const int INF=0x3f3f3f3f;int n,ope,X,head,tail,L,R;struct Node {    int l,r,mx;}tr[400005];void build(int i,int l,int r) {    tr[i].l=l;    tr[i].r=r;    tr[i].mx=-INF;    if(l==r)        return ;    int mid=(l+r)>>1;    build(lson,l,mid);    build(rson,mid+1,r);}void modify(int i) {//更改点L上的值    if(tr[i].l==tr[i].r) {        tr[i].mx=X;        return ;    }    if(L<=tr[lson].r)        modify(lson);    else        modify(rson);    tr[i].mx=max(tr[lson].mx,tr[rson].mx);}int query(int i) {//查找区间[L,R]上的最大值    if(L<=tr[i].l&&tr[i].r<=R) {        return tr[i].mx;    }    int mx=-INF;    if(L<=tr[lson].r)        mx=max(mx,query(lson));    if(tr[rson].l<R)        mx=max(mx,query(rson));    return mx;}int main() {    while(1==scanf("%d",&n)) {        build(1,1,n);        head=tail=1;        for(int i=0;i<n;++i) {            scanf("%d",&ope);            if(ope==1) {                scanf("%d",&X);                X-=i;//不耐烦程度都处理成时间0时的,方便查询最大值                L=tail++;                modify(1);            }            else if(ope==2) {                ++head;//队首元素出队,即查询区间往后推            }            else {                L=head;                R=n;//令区间右界为n,减少递归次数                printf("%d\n",query(1)+i);            }        }    }    return 0;}


解法二:单调队列

官方题解:



待完成

0 0
原创粉丝点击