BZOJ 1012 线段树||单调队列

非常裸的线段树  ||

单调队列:

假设一个节点在队列中既没有时间优势(早点入队)也没有值优势(值更大),那么显然不管在如何的情况下都不会被选为最大值。

既然它仅仅在末尾选。那么自然能够满足以上的条件。

线段树

#include "stdio.h"
#include "string.h"

struct node
{
    int l,r,Max;
}data[800010];

int Max(int a,int b)
{
    if (a<b) return b;
    else return a;
}

void build(int l,int r,int k)
{
    int mid;
    data[k].l=l;
    data[k].r=r;
    data[k].Max=0;
    if (l==r) return ;

    mid=(l+r)/2;

    build(l,mid,k*2);
    build(mid+1,r,k*2+1);
}

void updata(int w,int k,int op)
{
    int mid;
    if (data[k].l==w && data[k].r==w)
    {
        data[k].Max=op;
        return ;
    }

    mid=(data[k].l+data[k].r)/2;

    if (w<=mid) updata(w,k*2,op);
    else updata(w,k*2+1,op);

    data[k].Max=Max(data[k*2].Max,data[k*2+1].Max);
}

int query(int l,int r,int k)
{
    int mid;
    if (data[k].l==l && data[k].r==r)
        return data[k].Max;

    mid=(data[k].l+data[k].r)/2;

    if (r<=mid) return query(l,r,k*2);
    else if (l>mid) return query(l,r,k*2+1);
    else return Max(query(l,mid,k*2),query(mid+1,r,k*2+1));
}

int main()
{
    int m,d,t,x,now;
    char ch[2];
    while (scanf("%d%d",&m,&d)!=EOF)
    {
        build(1,m,1);
        t=0;
        now=0;
        while (m--)
        {
            scanf("%s%d",ch,&x);
            if (ch[0]=='A')
            {
                x=(x+t)%d;
                now++;
                updata(now,1,x);

            }else
            {
                t=query(now-x+1,now,1);
                printf("%d\n",t);
            }
        }
    }
    return 0;
}

单调队列:

#include "stdio.h"
#include "string.h"
int f[200010];
int main()
{
    int t,now,m,d,x,i;
    char ch[2];
    while (scanf("%d%d",&m,&d)!=EOF)
    {
        t=0;
        now=0;
        while (m--)
        {
            scanf("%s%d",ch,&x);
            if (ch[0]=='A')
            {
                f[++now]=(x+t)%d;
                for (i=now-1;i>=1;i--)
                if (f[i]<f[now]) f[i]=f[now];
                else break;
            }
            else
                printf("%d\n",t=f[now-x+1]);

        }
    }
    return 0;
}
时间: 2024-10-09 23:42:28

BZOJ 1012 线段树||单调队列的相关文章

【BZOJ-2892&amp;1171】强袭作战&amp;大sz的游戏 权值线段树+单调队列+标记永久化+DP

2892: 强袭作战 Time Limit: 50 Sec  Memory Limit: 512 MBSubmit: 45  Solved: 30[Submit][Status][Discuss] Description 在一个没有冬马的世界里,经历了学园祭后的春希着急着想要见到心爱的雪菜.然而在排队想见雪菜的fans太多了,春希一时半会凑不到雪菜面前. 作为高帅富,这样的问题怎么能难倒春希?春希从武也手中拿到了取自金闪闪宝库里的多啦A梦的传话筒,并且给每一个排队的fans都发了一个传话筒. 于

BZOJ 1012 线段树或单调队列

1012: [JSOI2008]最大数maxnumber 题意:两种操作:1.查询当前数列中末尾L个数中的最大的数:2.当前数列末尾插入一个数. tags:水题 线段树 #include<bits/stdc++.h> using namespace std; #pragma comment(linker, "/STACK:102400000,102400000") #define FF(i,a,b) for (int i=a;i<=b;i++) #define F(i

bzoj 1171 大sz的游戏&amp; 2892 强袭作战 (线段树+单调队列+永久性flag)

大sz的游戏 Time Limit: 50 Sec  Memory Limit: 357 MBSubmit: 536  Solved: 143[Submit][Status][Discuss] Description 大sz最近在玩一个由星球大战改编的游戏.话说绝地武士当前共控制了N个星球.但是,西斯正在暗处悄悄地准备他们的复仇计划.绝地评议会也感觉到了这件事.于是,准备加派绝地武士到各星球防止西斯的突袭.一个星球受到攻击以后,会尽快通知到总基地.需要的时间越长的星球就需要越多绝地武士来防御.为

BZOJ 1012 最大数maxnumber(单调队列)

Description 现在请求你维护一个数列,要求提供以下两种操作: 1. 查询操作.语法:Q L 功能:查询当前数列中末尾L个数中的最大的数,并输出这个数的值.限制:L不超过当前数列的长度. 2. 插入操作.语法:A n 功能:将n加上t,其中t是最近一次查询操作的答案(如果还未执行过查询操作,则t=0),并将所得结果对一个固定的常数D取模,将所得答案插入到数列的末尾.限制:n是非负整数并且在长整范围内.注意:初始时数列是空的,没有一个数. Input 第一行两个整数,M和D,其中M表示操作

BZOJ 1855 股票交易(单调队列优化DP)

题目链接:http://61.187.179.132/JudgeOnline/problem.php?id=1855 题意:最近lxhgww又迷上了投资股票, 通过一段时间的观察和学习,他总结出了股票行情的一些规律. 通过一段时间的观察,lxhgww预测到了未来T天内某只股票的走势,第i天的股票买入价为每股APi,第i天的股票卖出价为每股BPi(数据保证对于每 个i,都有APi>=BPi),但是每天不能无限制地交易,于是股票交易所规定第i天的一次买入至多只能购买ASi股,一次卖出至多只能卖出BS

pojBuy Tickets2828线段树(队列中倒序插队)

这题开始的思路就是模拟:就像数组中插点一样,每一个想买票的人都想往前插队! 但是这样的话肯定TLE, 看了别人的思路之后才恍然大悟! 正解: 将开始的正序插入,变成倒序插入,这样的话,想一想:第 i 个人想要插在 p[i] 的位置上,那么就要保证所插入的位置之前一定要有 p[i]-1个空位!因为一定会有p[j]<p[i] (0<=p[j]<=j,每个人都想往前插队) 的第j个人插在p[i]的位置的前边! 如果i<j; && p[i]==p[j], 倒序插入中,第j个

bzoj 1314: River过河 树套树+单调队列

Description ZY带N个小Kid过河,小KID分成两种:高一年级,高二年级,由于存在代沟问题,如果同一条船上高一年级生和高二年级生数量之差超过K,就会发生不和谐的事件.当然如果一条船上全是同一年级的,就绝对不会发生争执.现在ZY按小KID队列的顺序依次安排上船,并且不能让他们在过河时发生争执.对于当前等待上船的小KID来说,要么让他上船,要么将停在渡口的船开走,再让他上另一条船,同一条船上的人不过超过M人.为了让所有的小KID过河,在知悉小KID队列的情况下,最少需要多少条船. Inp

BZOJ 1791 岛屿(环套树+单调队列DP)

题目实际上是求环套树森林中每个环套树的直径. 对于环套树的直径,可以先找到这个环套树上面的环.然后把环上的每一点都到达的外向树上的最远距离作为这个点的权值. 那么直径一定就是从环上的某个点开始,某个点结束的. 把环拆成链,定义dp[i]表示第i个点为结束点的最远距离,显然有dp[i]=val[j]+sum[i]-sum[j-1]+val[i].显然可以用单调队列优化这个DP. 剩下的就是这样依次统计每个环套树的直径之和. 对于环套树上找环可以借鉴最小树形图找环的技巧. 首先将边定向,保证每个点的

bzoj 1791: [Ioi2008]Island 岛屿【基环树+单调队列优化dp】

我太菜了居然调了一上午-- 这个题就是要求基环树森林的基环树直径和 大概步骤就是找环->dp找每个环点最远能到达距离作为点权->复制一倍环,单调队列dp 找环是可以拓扑的,但是利用性质有更快好写的做法,就是像朱刘算法找环那样,按照输入的方向(i->to_i)打一圈标记,如果碰到同样标记就说明有环,这里注意我一开始没注意到的,从i点进入找到环不代表i点在环上,因为可能是6字形的,所以一定是环点的是找到的有同样标记的那个点,然后顺着这个点把环点都放进一个栈(其实不用,但是这样好写一些),顺着